[Java] 타입 변환

soheeoott·2021년 9월 4일
0

Java

목록 보기
6/12

타입 변환

데이터 타입을 다른 데이터 타입으로 변환하는 걸 의미한다.
종류로는 자동 타입 변환과 강제 타입 변환이 있다.

byteint
intdouble
doubleint
Stringint


자동 타입 변환(Promotion)

값의 허용 범위가 작은 타입이 큰 타입으로 저장될 때 발생한다.
데이터가 다른 데이터 타입으로 자동으로 변환된다.

큰 허용 범위 타입 = 작은 허용 범위 타입

기본 타입의 허용 범위

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;

리터럴 vs. 변수

자바에서는 컴파일 시 일부 연산을 수행한다.

리터럴
리터럴의 경우 자바 컴파일러가 연산을 수행한다.
타입이 정해지지 않은 상태이므로 선언한 타입에 맞춰 컴파일이 연산을 수행한 후 변수에 저장한다.

컴파일은 변수의 타입에 맞춰 연산을 수행한다.

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"

강제 타입 변환(Casting)

큰 허용 범위 타입을 작은 허용 범위 타입으로 변환한다.
이 때는 자동적으로 변환되지 않으므로 강제적으로 타입을 변환해야 한다.
캐스팅 연산자 괄호()를 사용해야 한다.

작은 허용 범위 타입 = (작은 허용 범위 타입) 큰 허용 범위 타입
  • 큰 허용 범위 타입을 작은 허용 범위 타입에 담을 수 있도록 나누고
  • 나누어진 부분 중 한 조각이 작은 허용 범위 타입으로 저장된다.
  • 이 때, 나머지 조각들은 버려진다.

int(4byte) 타입을 byte(1byte) 타입으로 쪼갠 뒤, 마지막 byte를 저장한다.

int intValue = 10;
byte byteValue = (byte) intValue; // 강제 타입 변환
// 10


int 타입 → char 타입

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"

혼공자 강의를 기반으로 작성하였습니다. 🙏
10강 11강 12강

profile
📚 글쓰는 습관 들이기 📚

0개의 댓글