[java] 변숴와 타입

‘\t’: 수평 탭 ‘\n’: 줄 바꿈 ‘\r’: 리턴 ‘"’: 큰 따옴표 ‘'’: 작은 따옴표 ‘\’:
‘\u16진수: 16진수 해당하는 유니코드

정수

byte: -128 ~ 127 1byte 8bit char: 0 ~ 2^16 -1 (유니코드) 2byte 16bit short: -2^15 ~ (2^15 - 1)(-32,768 ~ 32,767) 2byte 16bit int: -2^31~ (2^31 - 1)(-20억 ~ 20억) 4byte 32bit long: -2^63~ (2^63 - 1) 8byte 64bit

실수

float: 4byte 32bt double: 8byte 64bit

논리

boolean 1byte 8bit

자바는 모든 문자를 유니코드로 처리한다. 유니코드는 세계 각국의 문자들을 코드값으로 매핑한 국제 표준 규약이다. 유니코드는 0 ~ 65535 범위의 2byte 크기를 가진 정수 값이다.

프로그램 코드에서 char 변수에 저장된 유니코드를 알고 싶다면 char 타입 변수를 int 타입 변수에 저장하면 된다.

char c = ‘A’; int unicode = c;

char c1 = ‘A’; => A 출력 char c2 = 65; => A 출력 char c3 = ‘\u0041’ => A 출력

char c1 = ‘가’; => 가 출력 char c2 = ‘44032’; => 가 출력 char c3 = ‘\uac00’; => 가 출력

int unicode = c3 => 44032 출력

char c = ‘’; => 컴파일 에러 발생 char c = ‘ ‘; => 컴파일 에러 발생하지 않음

String str = “”; => 컴파일 에러 발생하지 않음

타입변환

자동(묵시적) 타입 변환

큰 크기 타입 <=(형변환 자동) 작은 크기타입

int intVal = 200; double doubleVal = intVal;

char charVal = ‘A’; int intVal = charVal; => intVal은 65가 저장된다.

한가지 예외로 char는 2byte 크기를 갖지만 char 범위는 0~65535 이므로 음수가 저장될 수 없다. 하여 byte 타입은 음수가 될 수 있음으로 char로 자동 변경이 될 수 없다.

byte byteVal = 65; char charVal = byteVal; => 컴파일에러 char charVal = (char) byteVal; => 강제 타입변환으로 가능은 하다.

강제 타입 변환

작은 크기 타입 <= (작은 크기 타입) 큰 크기 타입

4byte인 int 타입을 1byte인 byte 타입엔 담을 수 없다. 하지만 큰 그릇을 작은 그릇 사이즈로 쪼개어 한 조각만 작은 그릇에 넣는다면 가능하다. 즉 int 타입을 4개의 byte로 쪼갠 후 끝에 있는 1byte만 byte 타입 변수에 저장하는 것은 가능하다.

이와같이 강제적으로 큰 데이터 타입을 작은 데이터 타입으로 쪼개어서 저장하는 것을 강제 타입 변환(캐스팅)이라고 한다.

int intVal = 103029770; byte byteVal = (byte) intVal; // 강제 타입 변환

103029770인 4byte 메모리에 2진수로 00000110 00100100 00011100 00001010 으로 저장된다. 여기서 앞에 세 이진수 덩어리는 사라지고 끝의 이진수 덩어리만 byteVal에 저장되게 된다. 그래서 기존의 값인 103029770은 유지되지 않고 변형이 일어나며 저장되게 된다. 하지만 int의 끝 값이 1byte로 표현될 수 있다면 byte 타입으로 변환해도 같은 값이 유지될 수 있다.

int intVal = 10; byte byteVal = (byte)intVal; => 값이 유지되면서 byte로 표현가능

long longVal = 300; int intVal = (int)longVal; => 값이 유지되면서 int로 표현가능

int 타입은 char 타입으로 자동(묵시적) 타입 변환되지 않으므로 강제 타입 변환이 필요하다.

int intVal = ‘A’; char charVal = (char) intVal; => 65 출력

실수타입(float, double)은 정수타입(byte, short, int, long)으로 자동 변환되지 않기 때문에 강제 타입 변환이 필요하다. 이 경우 소수점 이하 부분은 버려지고 정수만 저장된다.

강제 타입변환에서 주의할 점은 사용자로부터 입력 받은 값을 변환할 때 값의 손실이 발생하면 안된다는 것이다.

int i = 128;

if((i < Byte.MIN_VALUE) || (i > Byte.MAX_VALUE)) { // byte 타입 변환 X } else { byte b = (byte) i; }

와 같은 분기 문으로 변환할 타입의 최소, 최대 값을 벗어나는지 검사한 뒤에 처리하는것이 좋다.

int 타입을 float 타입으로 변환할 때 주의할 점은 int 타입은 32비트로 표현되고 float은 부호 1비트, 지수 8 비트, 가수 23비트로 수를 표현하기 때문에 가수 23비트로 정수 32비트의 영역을 가진 int 타입을 전부 처리하기 힘들다. 그렇기 때문에 int 타입을 실수로 형변환할 때는 double 타입을 사용하는것이 가장 안전하다.

연산식에서의 자동 타입 변환

서로 다른 타입의 연산이 발생할 때는 두 피연산자 중 크기가 큰 타입으로 자동 변환된 후 연산을 수행한다. 예를들어 int 타입 피연산자와 double 타입 피연산자를 덧셈하면 먼저 int 타입 피연산자가 double 타입으로 자동 변환되고 연산을 수행한다. 당연히 연산의 결과는 double이 된다.

만약 int로 하고 싶다면 double 타입을 강제 형변환 하여 연산을 수행하며 된다.