본문 바로가기

Java/Java

타입 변환

1. 타입변환

타입 변환은 어떤 리터럴의 데이터 타입을 다른 데이터 타입으로 변환하는 것을 말한다. 

타입변환은 '자동 타입 변환'과 '강제 타입 변환'이 있다.

 

 

2. 자동 타입 변환

자동 타입 변환은 단어 그대로 타입 변환이 자동으로 이뤄지는 타입 변환이다.

숫자 데이터 타입(정수 및 실수)에서 자동 변환은 허용 범위가 작은 타입에서 허용 범위가 큰 타입으로 변환될 때 발생된다.

 

byte < short, char < int < long < float < double

 

그러나 예외가 존재한다. byte 타입은 short 타입으로 자동 변환 되지만, char 타입으로는 자동변환 되지 않는다.

byte 타입은 음수 값이 허용되지만, short 타입은 음수 값이 포함되지 않는다. 

즉,  short 타입이 byte 타입의 모든 허용 범위를 커버할 수 없기 때문이다. 

public class PromotionExample {

	public static void main(String[] args) {
		byte byteValue = 10;
		int intValue = byteValue;
		System.out.println("intValue: " + intValue);
		
		char charValue = '가';
		intValue = charValue;
		System.out.println("가의 유니코드: " + intValue);
		
		intValue = 50;
		long longValue = intValue;
		System.out.println("longValue: " + longValue);
		
		longValue = 100;
		float floatValue = longValue;
		System.out.println("floatValue: " + floatValue);
		
		floatValue = 100.5f;
		double doubleValue = floatValue;
		System.out.println("doubleValue: " + doubleValue);

	}

}

 

3. 강제 타입 변환

강제 타입 변환(casting)은 데이터 타입을 특정 명령어를 통해 변환해주는 것을 말한다. 

허용 범위가 큰 데이터 타입은 허용 범위가 작은 데이터 타입으로 자동 변환될 수 없다.

특정 명령어를 통해 강제 타입 변환을 해줘야한다. 

강제 타입 변환은 캐스팅 연산자 ()를 통해 실시된다.

public class CatstingExample {

	public static void main(String[] args) {
		int intValue = 10; //만약 intValue 값이 byte 허용범위를 넘어가는 정수라면, 넘어가는 만큼 범위를 돌아서 값이 저장된다. 예) 128 => -128, -129 => 127 
		byte byteValue = (byte) intValue;
		System.out.println(byteValue);
		
		
		int intValue2 = 65;
		char charValue = (char) intValue2;
		System.out.println(charValue);
		
		
		double doubleValue = 3.65;
		int intValue3 = (int) doubleValue; // 실수 => 정수의 형변환 시에는, 소수점 이하 반올림이 아닌 버림으로 처리된다.
		System.out.println(intValue3);

	}

}

 

4. 연산에서의 자동 타입 변환

1) 정수 타입 변수 중 int 타입 이하의 정수 타입 변수들(byte, char, short, int)은 int 타입으로 자동 변환되어 연산된다. 

 따라서, 연산 결과 또한 int 타입이므로, int 타입 이하의 정수 타입 변수에 저장될 수 없다. 

 

2) 정수 타입 변수 연산의 모든 경우에서 int 타입으로 자동 변환되는 것은 아니다.

기본적으로 정수 타입의 연산은 허용 범위가 큰 피연산자의 타입으로 변환되어 진행되기 때문에, long과 다른 정수 타입 변수가 연산되면 long 타입으로 변환되어 연산이 진행된다. 

 

public class LongOperationExample {

	public static void main(String[] args) {
		byte value1 = 10;
		int value2 = 100;
		long value3 = 1000l;
		long result = value1 + value2 + value3; //모든 정수연산이 int로 변환되어 실시되는 것이 아니다. 기본적으로 정수연산은 피연산자들 중 가장 허용범위가 큰 타입으로 변환되어 실행된다.
		System.out.println(result);

	}

}

 

3) 실수 타입 변수들이 피연산자일 때 피연산자들이 동일한 타입일 경우 해당 타입으로 연산이 진행된다.

그러나 하나의 변수라도 double 타입이라면, double이 실수 타입 중 허용 범위가 가장 크므로 double로 변환되어 연산이 수행된다.

 

4) 정수 타입 변수와 실수 타입 변수들이 연산될 경우, 가장 큰 허용 범위를 가진 실수 타입으로 변환되어 연산이 진행된다. 

public class OperationPromotionExample {

	public static void main(String[] args) {
		byte byteValue1 = 10;
		byte byteValue2 = 20;
		//byte byteValue3 = byteValue1 + byteValue2; //byte 타입 변수는 int로 변환되어 연산됨. 따라서 결과도 int 리터럴이므로 int 변수에 저장해야함.
		int intValue1 = byteValue1 + byteValue2;
		System.out.println(intValue1);
		
		char charValue1 = 'a';
		char charValue2 = 1;
		//char charValue3 = charValue1 + charValue2; // char 타입 변수도 int로 변환되어 연산됨.
		int intValue2 = charValue1 + charValue2;
		System.out.println("유니코드= " + intValue2);
		System.out.println("출력문자= " + (char) intValue2);
		
		int intValue3 = 10;
		int intValue4 = intValue3 / 4;
		System.out.println(intValue4);
		
		int intValue5 = 10;
		//int intValue6 = intValue5 / 4.0 //정수와 실수를 연살할 경우, 실수가 허용범위가 더 큰 변수타입이므로 실수의 기본 타입인 double로 변환되어 연산된다.
		double doubleValue  = intValue5 / 4.0;
		System.out.println(doubleValue);
		
		int x = 1;
		int y = 2;
		double result1 = x / y; //정수연산이 먼저 처리되고 실수 타입으로 저장됨. 
		double result2 = (double) x / y;
		double result3 = x / (double) y;
		double result4 = (double) (x / y); //정수연산이 먼저 처리되고 실수타입으로 캐스팅 후 저장.
		System.out.println(result1);
		System.out.println(result2);
		System.out.println(result3);
		System.out.println(result4);

	}

}

주의할 점은 산술연산에서 정수 -> 실수 타입의 변환도, + 연산자를 사용한 문자열 변환과 동일한 로직을 따른다는 것이다. 

예를 들어 int 타입 변수 x, y, z에 대해 연산식 x / y * z;를 수행하고 그 결과를 double 타입으로 산출하고자 할 때,

어느 위치에 double을 사용하냐에 따라 값이 달라진다.

정수는 실수와 연산되는 그 순간에 실수로 변환되며, 왼쪽에서 오른쪽의 연산 순서를 따른다.

int x = 36;
int y = 7;
int z = 14;

//double result = (double) x / y * z; // 72.0 
//double result =  x / (double) y * z; // 72.0
//double result =  x / y * (double) z; // 70.0
double result =  (double) (x / y * z); // 70.0
System.out.println(result);

 

5. 문자열의 타입 변환

1) + 연산을 통한 자동 타입 변환

+연산이 수행될 때, 피연산자 중 하나가 문자열 리터럴일 경우 나머지 피연산자도 문자열로 자동 변환 되어 문자열 결합 연산이 수행된다.

여기에서 주의할 점은 + 연산이 왼쪽에서부터 순차적으로 진행된다는 것이다.

+연산자를 통해 문자열과의 결합연산이 수행되기 전에는, 숫자 리터럴끼리 덧셈 연산이 수행된다.

public class StringConcatExample {

	public static void main(String[] args) {
		int value = 10 + 2 + 8;
		System.out.println("value: " + value); //20
		
		String str1 = 10 + 2 + "8";
		System.out.println("str1: " + str1); //128
		
		String str2 = 10 + "2" + 8;
		System.out.println("str2: " + str2); //1028
		
		String str3 = "10" + 2 + 8;
		System.out.println("str3: " + str3); //1028
		
		String str4 = "10" + (2 + 8);
		System.out.println("str4: " + str4); //1010

	}

}

 

2) 문자열의 강제 타입 변환

문자열에서 기본 타입으로 강제 변환

기본 타입에서 문자열로 강제 변환이 가능하다.

특정 명령어를 통해서 수행되는데, 타입별로 명령어는 다르지만 그 형태가 매우 유사하다.

public class PrimitiveAndStringConversionExample {

	public static void main(String[] args) {
		int value1 = Integer.parseInt("10");
		double value2 = Double.parseDouble("3.14");
		boolean value3 = Boolean.parseBoolean("true");
		
		System.out.println("value1: " + value1);
		System.out.println("value2: " + value2);
		System.out.println("value3: " + value3);
		
		
		String str1 = String.valueOf(10);
		String str2 = String.valueOf(3.14);
		String str3 = String.valueOf(true);
		
		System.out.println("str1: " + str1);
		System.out.println("str2: " + str2);
		System.out.println("str3: " + str3);
		
		long var1 = 2l;
		float var2 = 1.8f;
		double var3 = 2.5;
		String var4 = "3.9";
		int result = (int) (var1 + var2 + (int) var3 + Double.parseDouble(var4));
		System.out.println(result);
	}

}

 

출처: 혼자 공부하는 자바(신용권)

'Java > Java' 카테고리의 다른 글

제어문_조건문  (0) 2021.09.30
연산자  (0) 2021.09.19
메모리, 변수  (0) 2021.07.06
인터페이스  (0) 2021.06.15
상속  (0) 2021.06.08