[Java] Java의 데이터 타입 + 기본형과 참조형 비교분석

Yunjisoo·2023년 6월 2일
0

Java

목록 보기
2/2

Java의 데이터 타입

Java 프로그래밍 언어는 모든 변수를 사용하기 위해 가장 먼저 변수선언을 한다. 변수를 선언할 때 해당 데이터가 메모리에 어떻게 저장되고 프로그램에 어떻게 처리되었는지를 결정하기 위해 변수의 이름과 데이터타입을 정해야 한다.

Java의 데이터타입은 기본형 타입(primitive type)과 참조형 타입(reference tye)으로 분류할 수 있다. 쉽게 말하자면 값을 변수에 "어떻게" 저장하느냐로 구분지을 수 있다.

기본형(Primitive type)

Java는 총 8가지의 기본 데이터 유형을 가진다. 모든 기본 데이터 유형은 기본값을 가지고 있기 때문에 null값을 가질 수 없으며, 값을 저장하는 공간은 기본적으로 스택(Stack) 메모리이다.

종류데이터형메모리 크기기본값표현 범위
정수형byte1 byte0-2^7 ~ 2^7-1
정수형short2 byte0-2^15 ~ 2^15-1
정수형int4 byte0-2^31 ~ 2^31-1
정수형long8 byte0L-2^63 ~ 2^63-1
실수형float4 byte0.0F1.4 x 10^(-45) ~ 3.4 x 10^(38)
실수형double8 byte0.0d (d 생략가능)(1,7 10 ^ -308) ~(1.7 10^308)
문자형char            2 byte       '\u0000'      0 ~ 02^16-1
논리형boolean1 bytefalsetrue, false

정수형

byte : -2^7 ~ 2^7-1
short : -2^15 ~ 2^15-1
int : -2^31 ~ 2^31-1
long : -2^63 ~ 2^63-1

n비트는 2^n가지 정보를 표현할 수 있다. 1byte는 8비트이니 2^8개를 표현할 수 있다고 생각할 수 있다. 하지만 숫자형 데이터 타입에서는 맨 앞의 비트를 부호를 나타내는 비트로 사용하기에 바이트 크기에서 1작은 승수로 제한된다.
예시: byte는 8bit> 7bit로 제한. -128(=-2^7)부터 127(=2^7-1) 표현

JVM의 피연산자 스택은 피연산자를 4 Byte 단위로 저장하기 때문에 int보다 작은 자료형의 값을 계산할 때에는 int 형으로 형변환 되어 연산이 수행된다. byte나 short와 같은 작은 크기의 정수형 데이터를 계산하거나 연산해도 해당 값을 int로 형변환하여 연산하기 때문에 메모리 사용과 연산 결과에 주의해야 한다.

실수형

float
32비트(4바이트)를 사용하여 숫자 표현: 부호비트 1비트, 지수비트 8비트, 숫자비트 23비트
float은 싱글 프리시전을 나타내는데, 이는 IEEE 754 부동 소수점 표준을 따르는 32비트 데이터 타입이다. double보다 더 적은 메모리를 사용하며 큰 범위의 숫자를 표현할 수 있지만, 정밀도는 상대적으로 낮다. 약 6-7자리의 소수점 정밀도를 가지기 때문에 더 높은 정밀도가 필요한 경우 double 데이터 타입을 고려해보아야 한다.

double
64비트(8바이트)를 사용하여 숫자 표현: 부호비트 1비트, 지수비트 11비트, 숫자비트 52비트
double은 더블 프리시전을 나타내며 double보다 더 많은 메모리를 사용하며 더 큰 범위와 높은 정밀도를 제공한다. 약 15자리의 소수점 정밀도를 갖는다.

실수형 데이터 타입에서는 double을 기본 데이터형으로 갖기 때문에 구분을 위해 float형 데이터타입 표현 시맨 뒤 쪽에 접미사 'f'나 'F'를 붙여줘야 한다. 만일 생략 시 double형으로 인식된다.

문자형

char
자바는 문자열을 처리할 때, 기본적으로 UTF-16 인코딩 방식(모든 문자를 2바이트로 표현하는 고정 길이 인코딩 방식)을 사용한다. 이에 따라 한글은 2바이트로 표현된다. 위의 표에 나온대로 유니코드 문자를 저장하기 위해 char는 정수 형태로 사용될 수 있다.
예: char a='A' 일때, 변수 a는 'A'의 정수값인 65를 갖는다.

논리형

boolean
저장 가능한 범위는 true와 false 두가지 선택지가 있으며 각 1bit 공간만으로도 저장된다. 그러나 Java가 데이터를 다루는 최소 범위가 1 Byte이기 때문에 낭비적이지만 1 Byte를 사용한다.


참조형(Reference type)

종류

참조형은 문자열, 배열, 열거, 클래스, 인터페이스를 말한다.

Java에서 기본 타입 변수(예: int, char, boolean)는 스택 영역에 실제 값을 저장한다. 참조 타입 변수(예: 문자열, 배열, 클래스, 인터페이스)은 힙 영역에 실제 객체가 생성되고, 스택 영역의 참조 타입 변수는 해당 객체의 주소를 가리킨다.

즉, 참조 타입 변수를 사용하면 객체의 주소를 스택에 저장하고, 해당 객체를 사용할 때마다 주소를 참조하여 실제 객체에 접근한다. 이렇게 함으로써 객체를 생성하고 사용하는 데 필요한 메모리를 효율적으로 관리할 수 있다.

기본 타입 변수
int a = 10;

참조 타입 변수
String n = "abcd";

위의 코드를 그림화하면 아래와 같다.

Stack영역은 객체 안의 메소드의 작업이 종료되면 할당되었던 메모리 공간은 반환되어 비워진다.
그리고 Heap영역은 참조하는 변수가 없으면 더이상 사용하지 않는 객체를 자동으로 가비지 컬렉터가 제거해준다.

Boxing과 Unboxing이란?

Boxing은 기본형을 해당하는 래퍼 클래스(Wrapper class)로 변환하는 과정을 말한다. 예를 들어, int를 Integer로 변환하는 것을 Boxing이라 한다. Unboxing은 반대로, 참조형을 해당하는 기본형으로 변환하는 과정을 말한다. 예를 들어, Integer를 int로 변환하는 것은 Unboxing이다.

Java 1.5 이전에는 Boxing과 Unboxing을 명시적으로 Boxing이나 Unboxing을 해주어야 했다. Java 1.5부터는 Auto기능이 도입되어 int를 Integer로 할당하면 자동으로 Boxing이 처리되고, Integer를 int에 할당하면 자동으로 Unboxing이 처리된다.
/ Auto Boxing / Unboxing 기능은 메모리 누수의 원인이 될 수도 있다. /

<예시>
  Java 1.5 이전
  Integer integer = new Integer(i); //int를 Integer로 Boxing
  
  1.5 이후
  int i = 10;
  Integer integer = i;  // int가 Integer로 자동 Boxing


기본형과 참조형의 차이는?

1. Null 포함 가능 여부

기본형은 null 값을 가질 수 없고, 참조형은 null 값을 가질 수 있다.

int i = null;      // 컴파일 에러
Integer integer = null;  // 가능

2. 제네릭 타입에서 사용 가능 여부

기본형은 제네릭의 인자로 사용될 수 없다. 그러므로 제네릭 클래스 또는 제네릭 인터페이스의 인자로 기본형을 사용할 수 없다. 참조형은 제네릭의 인자로 사용될 수 있다. 제네릭 클래스나 제네릭 인터페이스에서는 참조형을 사용하여 인자로 전달할 수 있다.

List<int> primitive_with_generic;      // 컴파일 에러
List<Integer> reference_with_generic;  // 가능

3. 접근 속도/ 메모리 용량 차이

참조형은 기본형보다 더 많은 유연성과 기능을 제공한다. 그렇다면 기본형은 어떤 이점이 있을까? 바로 메모리 사용량과 연산 속도 면에서 더 효율적일 수 있다.

* 접근 속도


기본형은 값 자체를 스택 메모리에 저장하므로 접근이 빠르다. 반면에 참조형은 객체의 참조를 스택 메모리에 저장하고 실제 값은 힙 메모리에 저장되므로, 값을 사용할 때마다 언박싱(Unboxing) 과정을 거쳐야 한다. 이로 인해 기본형은 접근 속도가 더 빠르고, 참조형보다 빠른 연산이 가능하다.

* 메모리 사용량

기본형은 참조형에 비해 적은 메모리를 사용한다. 기본형은 해당 타입의 크기에 따라 고정된 메모리를 사용하고, 참조형은 객체의 상태와 메서드 등을 포함한 추가적인 메모리를 사용한다. 따라서 기본형을 사용하면 고정된 메모리를 사용해 계획적으로 메모리 사용량을 줄일 수 있다.



참고사항
여러 글을 참고하다보면 같은 의미인데도 다른 단어를 사용하는 경우가 있다. 이는 영어를 한국어로 번역하는 과정에서 생긴 일이므로 다음과 같은 단어는 동의어임을 기억해두자. 참고로 나는 기본형, 참조형을 사용했다.
Primitive type: 원시 타입, 원시형, 기본형, 기본 타입 등..
Reference type: 참조 타입, 참조형 등..


참고 사이트

Java에서 원시타입 vs 참조타입 어떤 걸 사용해야 할까?

Java Primitive type 에 대해 알아보자 (용어정리)

원시타입, 참조타입(Primitive Type, Reference Type)

The Java™ Tutorials :Primitive Data Types

[ JAVA ] JVM이 문자열을 UTF-16 방식으로 저장하는 이유

[Java] 참조 타입과 참조 변수

profile
기초부터 시작

0개의 댓글