자료형의 종류
크게 기본 자료형과 참조 자료형으로 나뉜다. 기본 자료형은 8가지(boolean, byte, short, int, long, float, double, char)가 있고, 참조 자료형(배열, 클래스, 인터페이스)은 개발자가 직접 정의할 수도 있어서 무한대이다. 두 가지로 나누는 이유는 값을 저장하는 방법이 다르기 때문이다.
기본 자료형과 참조 자료형의 차이
기본 자료형(int, long, float, double, ...)은 모두 소문자로 시작하고, 참조 자료형(String, System, ...)은 모두 대문자로 시작한다. 기본 자료형은 스택 메모리에 생성된 공간에 실제 변숫값을 저장하는 반면, 참조 자료형은 실제 데이터 값은 힙 메모리에 저장하고 스택 메모리의 변수 공간에는 실제 변수 값이 저장된 힙 메모리의 위칫값을 저장한다. 즉, 기본 자료형의 변수는 데이터를 저장하고 참조 자료형의 변수는 주소 값을 저장한다.
메모리
메모리는 목적에 따라 3가지로 나뉜다. 첫 번째 영역은 클래스 영역, 정적 영역, 상수 영역, 메서드 영역으로 불린다. 두 번째 영역은 스택 영역으로 변수가 저장되는 공간이다. 세 번째 영역은 힙 영역으로 객체가 저장되는 공간이다.
기본자료형의 메모리 크기와 저장할 수 있는 값의 범위
자료형 | 자료의 크기 | 값의 범위 | |
부울대수 | boolean | 1byte | true, false |
정수 | byte | 1byte | -27 ~ 27-1 |
short | 2byte | -215 ~ 215-1 | |
int | 4byte | -231 ~ 231-1 | |
long | 8byte | -263 ~ 263-1 | |
실수 | float | 4byte | ±(1.40 x 10-45 ~ 3.40 x 1038) |
double | 8byte | ±(4.94 x 10-324 ~ 1.79 x 10308) | |
문자(정수) | char | 2byte | 유니코드 문자(0~216-1) |
n개의 비트로 표현할 수 있는 정수는 2n개다. 1바이트는 8비트이므로 표현할 수 있는 정수는 28(=256)개 이다. 정수는 음수, 0, 양수를 포함하므로, 표현할 수 있는 전체 개수 중 반은 음수, 나버지 반은 0과 양수에 할당한다. 그 결과 바이트 자료형의 범위는 -27 ~ 27-1이다. 같은 방법으로 나머지 정수 자료형도 값의 벙위를 알 수 있다. 다음으로 실수 자료형은 float, double이 있고 이들의 값의 범위는 정수에 비해 훨씬 넓다. 이는 실수의 저장 방식이 부동 소수점의 형태(가수X밑지수)로 저장하기 때문이다. float에는 부호 1bit, 가수 23bit, 지수 8bit가 할당되고, double에는 부호 1bit, 가수 52bit, 지수 11bit가 할당된다.
부울대수
boolean은 ture(참)과 flase(거짓)의 값만 저장할 수 있는 자료형이다. 2가지 값만 표현하면 되므로 1bit면 충분하나, 자료 처리의 최소 단위가 바이트 이므로 1byte가 할당된다. 따라서 상위 7bit는 사용하지 않는다.
정수
대입식 | 정수 리터럴의 자료형 인식 |
byte a = 3; | byte에 저장할 수 있는 값이 byte 자료형에 대입되면 byte로 인식(byte=byte) |
short a = 3; | short에 저장할 수 있는 값이 short 자료형에 대입되면 short로 인식(short=short) |
int a = 3; | int와 같거나 int보다 큰 정수 자료형(long)에 정숫값이 입력되면 크기와 관계없이 int로 인식(int=int) |
long a = 3L; | 정수 리터럴 뒤에 L(또는 l)이 붙으면 long으로 인식(long=long) |
long a = 3; | long자료형에 대입되는 정숫값은 크기에 상관없이 int로 인식되지만, 자동 타입 변환이 발생해 long으로 변환(long=long) |
byte a = 130; | byte에 저장할 수 없는 범위의 정숫값이 입력되면 int로 인식(byte=int) -> 오류 발생 |
정수를 저장할 수 있는 자료형은 4가지이다. 메모리 효율성을 위해 크기가 다른 4가지 그릇이 준비된 셈이다. 자바에선 항상 대입 연산자(=)를 중심으로 양쪽의 자료형이 동일해야 한다. 코드에서 직접 작성한 값을 리터럴literal이라고 한다. 컴파일러는 리터럴을 어떤 자료형으로 저장할지 결정해야 한다. 정수 리터럴은 byte와 short 자료형에 저장할 수 있는 범위 내의 정숫값이 입력되면 각각 byte, short 자료형으로 인식한다. 반대로, byte, short의 범위를 넘어가면 모두 int로 인식한다. long 자료형으로 인식하게 하고 싶다면 정수 리터럴 뒤에 L(또는 l)을 붙이면 된다. 만약, 붙이지 않아도 크기가 작은 자료형을 큰 자료형에 대입하면 컴파일러가 자동 타입 변환을 수행하기 때문에 오류는 일어나지 않는다. 하지만 반대로 큰 자료형을 작은 자료형에 대입하는 경우, 자동 타입 변환을 하지 않기 때문에 문법 오류가 발생한다.
실수
대입식 | 실수 리터럴의 자료형 인식 |
float a = 3.5F; | 뒤에 F가 붙었으므로 float으로 인식(float=float) |
double a = 5.8; | 실수 리터럴은 기본적으로 double로 인식(double=double) |
double a = 5; | int로 인식하지만 자동 타입 변환해 double로 인식(double=double) |
float a = 3.5; | 실수 리터럴은 기본적으로 double로 인식(float=double) -> 오류 발생 |
실수 리터럴은 float과 double, 두 가지 자료형이 있다. 실수 리터럴은 기본적으로 double로 인식하고, F(또는 f)를 뒤에 붙여서 float 자료형으로 인식시킬 수 있다.
문자
char 자료형은 문자를 작은따옴표('') 안에 표기한다. 자바는 세상의 모든 문자에 정숫값을 매겨 넣은 표인 유니코드unicode 표를 이용하여 문자를 입력하고 출력한다. char 자료형은 문자를 입력해도 되고, 정숫값 또는 유니코드값을 직접 입력할 수 있다.
문자 'A'를 저장하는 다양한 방법 |
char a = 'A'; // 문자 char b = 65; // 10진수 (숫자) char c = 0b1000001; // 2진수 (0b + 숫자) char d = 00101; // 8진수 (0 + 숫자) char e = 0x0041; // 16진수 (0x + 숫자) char f = '\u0041'; // 유니코드 (\u + 16진수) |
기본 자료형 간의 타입 변환
boolean을 제외한 기본 자료형 7개는 자료형을 서로 변환 가능하다. 변환 방법은 변환 대상 앞에 (자료형)만 표기하면 된다. 정수나 실수 리터럴은 숫자 뒤에 L이나 F를 붙여 각각 long, float으로 타입 변환을 수행할 수도 있다.
자료형 간의 타입 변환 방법 |
자료형 변수명 = (자료형) 값; long 변수명 = 값 + L; long 변수명 = 값 + l; float 변수명 = 값 + F; float 변수명 = 값 + f; |
타입 변환을 수행할 때는 저장할 수 있는 값의 범위나 종류가 달라지므로 값이 변할 수 있음에 주의해야 한다. 타입 변환에는 컴파일러가 자동으로 수행하는 자동 타입 변환과 개발자가 직접 타입 변환을 수행하는 수동 타입 변환이 있다. 아까 봤던 작은 자료형을 큰 자료형에 대입할 때 컴파일러가 자동으로 타입 변환을 해주는 것을 업캐스팅up-casting이라 한다. 업캐스팅이 아닌데도 자동 타입 변환이 적용되는 때가 있다. 사실 모든 정수 리터럴값은 int로 인식하는데 byte, short에 저장할 수 있는 범위 내의 정수 리터럴이 대입될 때 자동 타입 변환이 실행돼서 각각의 자료형으로 인식할 수 있다. 업캐스팅의 반대로 다운캐스팅down-casting이 있는데 큰 자료형을 작은 자료형에 대입하는 행위를 말한다. 데이터 손실이 발생할 수 있기 때문에 자동으로 변환되지 않고 개발자가 직접 해줘야 한다. 자료형의 크기는 byte < short/char < int < long < float < double의 순서로 커진다.
기본 자료형 간의 연산
연산 | 결과 |
byte + short | int |
byte + int | int |
short + long | long |
int + float | float |
long + float | float |
float + double | double |
boolean을 제외한 나머지 기본 자료형은 서로 연산할 수 있다. 같은 자료형을 더하면 같은 자료형이 나온다. 서로 다른 자료형을 연산할 경우 자동 업캐스팅에 의해 더 큰 자료형으로 변환되어 계산된다. byte + short 연산의 경우, CPU에서 연산 최소 단위가 int이므로 int보다 작은 자료형도 일단 int로 읽어오기 때문에 결과가 int로 나온다. 따라서, 같은 자료형 일지라도 byte + byte, short + short 연산의 결과도 int다. 여기선 더하기(+) 연산만 표시했지만, 모든 연산에 똑같이 적용된다.
타입 변환 메서드
문자열 -> 정수 : Integer.parselnt(문자열)
문자열 -> 실수 : Double.parseDouble(문자열)
정수 -> 문자열 : String.valueOf(정수)
실수 -> 문자열 : String.valueOf(실수)
'development > Java' 카테고리의 다른 글
JAVA 공부 해볼까 (6) (0) | 2021.12.11 |
---|---|
JAVA 공부 해볼까 (5) (0) | 2021.12.10 |
JAVA 공부 해볼까 (3) (2) | 2021.12.07 |
JAVA 공부 해볼까 (2) (4) | 2021.12.06 |
JAVA 공부 해볼까 (1) (4) | 2021.12.06 |