데이터 타입을 다른 데이터 타입으로 변환하는 걸 의미한다.
종류로는 자동 타입 변환과 강제 타입 변환이 있다.
byte
→ int
int
→ double
double
→ int
String
→ int
값의 허용 범위가 작은 타입이 큰 타입으로 저장될 때 발생한다.
데이터가 다른 데이터 타입으로 자동으로 변환된다.
큰 허용 범위 타입 = 작은 허용 범위 타입
byte < short < char < int < long < float < double
변수의 값을 다른 타입의 변수에 저장할 때 자동 타입 변환이 발생한다.
단, 저장할 변수의 타입은 더 큰 범위를 갖고 있어야 한다.
byte byteValue = 10;
int intValue = byteValue; // byte < int
char charValue = 'A';
int intValue = charValue; // char < int
// 65 (유니코드 값이 저장된다.)
char 타입에는 음수가 없기 때문에,
음수를 갖는 타입을 char 타입으로 변환하려 하면 컴파일 에러가 발생한다.
byte byteValue = 65;
char charValue = byteValue; // 컴파일 에러
연산으로 인해 int 타입의 범위 보다 작은 x와 y의 값이 int 타입으로 변환된다.
이 때, int 타입은 byte 타입으로 저장할 수 없으므로 컴파일 에러가 발생한다.
byte x = 10;
byte y = 20;
byte result = x + y; // 컴파일 에러
int result = x + y;
피연산자 중 하나가 더 큰 범위를 갖는 경우 큰 범위의 타입으로 변환된다.
이 때, long 타입은 int 타입으로 저장할 수 없으므로 컴파일 에러가 발생한다.
byte x = 30;
long y = 40;
int result = x + y; // 컴파일 에러
long result = x + y;
byte value1 = 10;
int value2 = 100;
long value3 = 1000L;
byte result = value1 + value2 + value3; // 컴파일 에러
int result = value1 + value2 + value3; // 컴파일 에러
long result = value1 + value2 + value3; // 1110
char 타입은 하나의 문자를 저장할 수 있지만,
정확히는 유니코드의 값을 가지므로 정수와 연산을 수행할 수 있다.
이 때, 연산 결과를 char 타입으로 강제 변환하면 유니코드 값을 문자로 출력한다.
char charValue1 = 'A';
char charValue2 = 1;
int intValue1 = charValue1 + charValue2; // 66
char charValue3 = (char) intValue1; // B
마찬가지로 피연산자 중 하나가 더 큰 범위를 갖는 경우 큰 범위의 타입으로 변환된다.
int intValue = 7;
double doubleValue = 7.7;
double result = intValue + doubleValue; // 14.7
다른 타입으로 연산을 하려면 타입을 강제로 변환하고 나서 연산을 수행해야 한다.
소수점이하의 수는 버려지므로 반올림 되지 않는다.
int intValue = 7;
double doubleValue = 7.7;
int result = intValue + (int) doubleValue; // 14
컴파일러는 기본적으로 실수값을 double 타입으로 인식하기 때문에
float 타입의 변수는 리터럴 뒤에 f 또는 F를 적어주어야 한다.
double result = 1.5 + 2.3;
float result = 1.5 + 2.3; // 컴파일 에러
float result = 1.5f + 2.3f;
정수의 산술 연산의 결과는 정수이다.
수학식에서는 1을 2로 나누면 0.5가 되지만, 자바에서는 0이된다.
그렇다고 해서 실수 타입으로 값을 저장해도 0.0이라는 값을 갖는다.
int x = 1;
int y = 2;
double result = x / y; // 0.0
일반 수학식처럼 계산된 값을 얻으려면 연산하기 전 타입 변환이 필요하다.
변환한 실수 타입(double)과 연산하면 정수는 실수로 변환된다.
// 방법 1
int x = 1;
int y = 2;
double result = (double) x / y; // (1.0 / 2.0 = 0.5)
// 방법 2
int x = 1;
int y = 2;
double result = x / (double) y;
// 방법 2
int x = 1;
int y = 2;
double result = (double) x / (double) y;
자바에서는 컴파일 시 일부 연산을 수행한다.
리터럴
리터럴의 경우 자바 컴파일러가 연산을 수행한다.
타입이 정해지지 않은 상태이므로 선언한 타입에 맞춰 컴파일이 연산을 수행한 후 변수에 저장한다.
컴파일은 변수의 타입에 맞춰 연산을 수행한다.
byte result = 10 + 20;
변수
변수에 저장한 리터럴을 연산하게 되면 자바 컴파일러는 연산을 수행하지 않는다.
컴파일이 아닌, 컴파일 된 결과를 실행하는 JVM에서 연산을 수행한다.
이 때, 타입이 int 타입 보다 작다면 int 타입으로 변환시킨다.
JVM은 int 타입으로 변환한다.
byte x = 10;
byte y = 20;
int result = x + y;
피연산자 중 하나가 문자열이라면 나머지 피연산자도 문자열로 자동 변환된다.
문자열과 + 연산을 하면 다른 피연산자도 문자열로 변환되어 문자열 결합이 발생한다. (문자열 결합 연산)
int intValue = 3 + 4; // 7
String str = 3 + "4"; // 34
String str = "3" + 4; // 34
+ 연산은 앞에서부터 순차적으로 수행
결합 연산이 먼저 수행되면 이후의 연산들은 모두 결합 연산이 된다.
괄호가 있다면 괄호안의 연산이 먼저 수행된다.
String str = 1 + 2 + "3";
// 3(1+2) + "3"
// "33"
String str = 1 + "2" + 3;
// "12" + 3
// "123"
String str = "10" + (2 + 8);
// 10(2 + 8) + "10"
// "1010"
큰 허용 범위 타입을 작은 허용 범위 타입으로 변환한다.
이 때는 자동적으로 변환되지 않으므로 강제적으로 타입을 변환해야 한다.
캐스팅 연산자 괄호()를 사용해야 한다.
작은 허용 범위 타입 = (작은 허용 범위 타입) 큰 허용 범위 타입
int(4byte) 타입을 byte(1byte) 타입으로 쪼갠 뒤, 마지막 byte를 저장한다.
int intValue = 10;
byte byteValue = (byte) intValue; // 강제 타입 변환
// 10
int 타입이 더 큰 범위를 갖고 있으므로 강제로 타입을 변환해야 한다.
char 타입으로 강제 변환하면 정수값이 유니코드값으로 저장된다.
int intValue = 65;
char charValue = (char) intValue;
System.out.println(charValue); // A
실수 타입이 더 큰 범위를 갖고 있으므로 강제로 타입을 변환해야 한다.
소수점 이하 부분은 버려지고 정수 부분만 저장된다.
double doubleValue = 3.14;
int intValue = (int) doubleValue; // 3
String 타입을 기본 타입으로 변환하려면 강제로 타입을 변환해야 한다.
이 때, 캐스팅() 연산자가 아닌 자바가 제공하는 API 클래스를 사용한다.
API 클래스가 가지고 있는 메소드에 변환할 대상을 적어주면 된다.
변환 타입 | API 클래스 | 사용 예 |
---|---|---|
String → byte | Byte.parseByte() | String str = "10"; byte value = Byte.parseByte(str); |
String → short | Short.parseShort() | String str = "10"; short value = Short.parseShort(str); |
String → int | Integer.parseInt() | String str = "10"; int value = Integer.parseInt(str); |
String → long | Long.parseLong() | String str = "10"; long value = Long.parseLong(str); |
String → float | Float.parseFloat() | String str = "3.14"; float value = Float.parseFloat(str); |
String → double | Double.parseDouble() | String str = "3.14"; double value = Double.parseDouble(str); |
String → boolean | Boolean.parseBoolean() | String str = "true"; boolean value = Boolean.parseBoolean(str); |
문자열이 숫자가 아닌 요소를 포함하고 있을 때 타입 변환을 시도하면
숫자 형식 예외 NumberFormatException
가 발생한다.
str = "7test";
int value = Integer.parseInt(str); // NumberFormatException 예외
기본 타입을 문자열로 변환하는 방법은 두 가지가 있다.
빈 문자열("") 결합
문자열과 숫자를 연산하면 결합 연산이 일어난다.
아무것도 입력하지 않은 빈 문자열와 숫자를 더하면 숫자는 문자열로 변환된다.
int value = 7;
String str = "" + 7; // "7"
String.valueOf() 메소드 사용
String.valueOf()
메소드를 사용하면 기본 타입을 문자열로 변환할 수 있다.
int value = 7;
String str = String.valueOf(value); // "7"