java에서 자료형은 '기본형'과 '참조형'으로 나뉜다. 기본형 변수는 실제 값을 저장하지만, 참조형 변수는 어떤 값이 저장되어 있는 주소를 저장한다.
기본형에는 흔히 우리가 알고 있는 boolean, char, byte, short, int, log, float, double 총 8개가 있고, 그 외에 나머지.. 예를 들어 클래스, 배열 등은 전부 참조형이다.
boolean, byte는 1바이트
char, short는 2바이트
int, float은 4바이트
long, double은 8바이트의 크기를 차지한다.
일반적으로 int는 CPU가 가장 효율적으로 처리할 수 있는 타입이기 때문에 많이 사용한다.
숫자 뒤에 l을 붙이면 long 타입으로 인식한다.
실수형은 기본적으로 아무것도 붙이지 않으면 double로 인식되고, f를 붙이면 float으로 인식된다.
d를 붙이면 double로 인식된다.
java에서 상수는 변수의 타입 앞에 "final" 키워드를 붙여줌으로써 선언된다.
final int MAX_SPEED = 10;
또한 반드시 선언과 동시에 초기화해야 하며 그 이후로는 값을 변경하지 못한다.
리터럴은 값을 의미하는데, 예를 들어 위에서 MAX_SPEED 변수가 상수라면, 그 값인 10은 리터럴이라고 말한다.
한 자리의 2진수를 비트라고 하며, 1비트는 컴퓨터가 값을 저장할 수 있는 최소 단위다. 그러나 1비트는 너무 작은 단위이기 때문에 1비트 8개를 묶어 바이트로 정의해 데이터의 기본 단위로 사용한다.
워드라는 단위도 있는데, 워드는 CPU가 한 번에 처리할 수 있는 데이터의 크기를 의미한다. 32비트 CPU에서 워드는 32비트 -> 4바이트이고 64비트 CPU에서는 64비트 -> 8바이트다.
어떠한 자료형을 가진 한 변수가 가질 수 있는 수의 범위를 넘어가면, 오버플로우가 발생한다. 정수형에선 예상하지 못한 숫자로 나타나지만 실수형에서는 그 값이 무한대가 된다.
또 정수형에는 없는 언더플로우가 있는데, 언더플로우는 실수형으로 표현할 수 없는 아주 작은 값, 즉 양의 최소값보다 작은 값이 되는 경우를 말한다. 이 때 변수의 값은 0이 된다.
실수형 자료형 double과 float에는 정수형에는 없는 정밀도란 것이 존재하는데, float는 7자리고 double은 15자리다. 이는 a * 10^n ( 1 <= a < 10 )으로 표현되는 7자리 or 15자리의 10진수를 오차없이 저장할 수 있다는 뜻이다.
따라서 연산속도의 향상이나 메모리를 절약하려면 float을 선택하고, 더 큰 값의 범위나 더 높은 정밀도를 필요로 하면 double을 선택해야 한다.
여러가지 형변환이 있지만, 정수형을 실수형으로 형변환하는 경우를 먼저 보면, 정수는 소수점이하의 값이 없으므로 간단하다. 정수를 2진수로 변환하여 정규화를 거쳐 실수의 저장형식으로 저장한다. 다만, 실수형 자료형은 정밀도의 제한이 있기 때문에 10진수로 8자리 이상의 값을 실수형으로 변환하는 경우에는 자료형에 따라 오차가 생길 수 있다.
실수형을 정수형으로 형변환할 때는, 실수형의 소수점이하 값은 전부 버려진다. 반올림도 하지 않는다. 만약 실수의 소수점을 버리고 남은 정수가 정수형의 저장범위를 넘는 경우에는 오버플로우가 발생한다.
형변환을 할 때에는, 표현범위가 좁은 타입에서 넓은 타입으로 변환해야 값 손실이 없으므로, 그렇게 변환하는 것을 추천한다.
자바는 타입 검사를 느슨하게 하는 편이다. (많이는 아니지만 적어도 go언어보단)
float f = 1234;
위와 같은 선언에서 1234는 정수지만, 컴파일하면 에러가 없다. 컴파일러가 자동으로 타입을 추론하고 1234를 float타입인 1234.00000...으로 변경하기 때문이다. 즉,
float f = (float)1234;
이것과 같다. 이를 자동 형변환이라고 한다.
그렇다면 어떤 기준으로 컴파일러가 자동 형변환을 실행할까? 바로 기존의 값을 최대한 보존할 수 있는 타입으로 자동 형변환한다.
표현 범위가 좁은 타입에서 넓은 타입으로 형변환해야 값 손실이 없으므로 서로 타입이 다른 두 쪽중에 표현 범위가 더 넓은 쪽으로 형변환된다.
예외적으로, char와 short는 둘 다 2바이트지만 char의 범위는 0~65535인 반면 short는 -32768~32767이므로 서로 범위가 달라 어느 쪽으로도 값 손실이 발생할 수 있으므로 자동 형변환이 불가능하다.