2014년 9월 2일 화요일

Java 변수(6-형변환)

3. 형변환

3.1 형변환(casting)이란?

모든 리터럴과 변수에는 타입이 있습니다. 프로그램을 작성하다 보면, 서로 다른 타입의 값으로 연산을 수행해야하는 경우가 생기게 됩니다.
 모든 연산은 기본적으로 같은 타입의 피연산자간에만 수행될 수 있으므로, 서로 다른 타입의 피연산자간의 연산을 수행해야하는 경우, 연산을 수행하기 전에 형변환을 통해 같은 타입으로 변환해 주어야 합니다.
형변환이란, 변수 또는 리터럴의 타입을 다른 타입으로 변환하는 것입니다.

3.2 형변환의 방법

기본형과 참조형 모두 형변환이 가능하지만, 기본형과 참조형 사이에는 형변환이 성립되지 않습니다. 기본형은 기본형으로만 참조형은 참조형으로만 형변환이 가능합니다.
 형변환 방법은 형변환하고자 하는 변수나 리터럴 앞에 변환하고자하는 타입을 괄호와 함께 붙여 주면 됩니다.

int score = (int)85.4; // double형 값을 int형으로 변환하여 score에 85를 저장합니다.          
byte b = (byte)score; //score에 저장된 값을 byte형으로 변환하여 byte에 저장합니다.        

피연산자 앞에 변환하고자 하는 타입의 이름을 괄호에 넣어 붙여주기만 하면 됩니다. 형변환에서 사용되는 괄호는 '케스트 연산자'또는 '형변환 연산자'라고 하며, 형변환을 '캐스팅(casting)'이라고 합니다.
캐스트 연산자는 피연산자의 값을 읽어서 지정된 타입으로 형변환하고 그 결과를 반환한다. 그래서 피연산자는 형변환 후에도 아무런 변환가 없습니다.

캐스팅 변환예제

public class Casting1 {

public static void main(String[] args) {
double d= 100.0;
int i = 100;
int result = i + (int)d;
System.out.println("i="+i);
System.out.println("d="+d);
System.out.println("result="+result);

}

}

실행결과
i=100
d=100.0 <- 형변환 이후에 아무런 변화가 없습니다.
result=200

double형 변수 d와 int형 변수 i의 덧셈연산을 하기 위해 캐스트 연산자를 이용해서 변수 d를 int형으로 변환하여 덧셈연산을 합니다. 그리고 그 결과를 int형과 int형의 연산결과는 항상 int형의 값을 결과로 얻으므로 result타입을 int로 하였습니다.
 위의 예제를 보면 d=100.0으로 형변환 후에도 변수 d에 저장된 값에는 변함이 없습니다.

3.3 기본형의 형변환

8개의 기본형 중에서 boolean을 제외한 나머지 7개의 기본형 간에는 서로 형변환이 가능합니다.
                                             형변환           수식          결과  
 int -> char     (char)65         'A'   
char -> int      (int)'A'           65    
float -> int      (int)1.6f          1     
   int -> float     (float)10       10.0f

각 자료형 마다 표현할 수 있는 값의 범위가 다르기 때문에 범위가 큰 자료형에서 범위가 작은 자료형으로의 변환은 값 손실이 발생할 수 있다.
예를 들어 실수형을 정수형으로 변환하는 경우 소수점 이하의 값은 버려지게 된다. 위에서의 예와 같이 float형 1.6f를 int로 변환하면 1이 된다.
반대로 범위가 작은 자료형에서 큰 자료형으로 변환하는 경우에는 절대로 값 손실이 발생하지 않으므로 변환에 아무런 문제가 없다.

int형과 byte간의 형변환 예제
public class Casting2 {

public static void main(String[] args) {
byte a = 10;
int i = (int)a;
System.out.println("a="+a);
System.out.println("i="+i);
int i2=100;
byte a2=(byte)i2;
System.out.println("i2="+i2);
System.out.println("a2="+a2);

}

실행결과
a=10
i=10
i2=100
a2=100

byte형을 int형으로, int형을 byte형으로 변환하고 그 결과를 출력하는 예제입니다.
 byte과 int 모두 정수형으로 크기는 1byte와 4byte이며, 표현할 수 있는 값의 범위는 byte가 -2^7~2^7-1(-128~127), int가 -2^31~2^31-1입니다. byte의 범위를 int가 포함하고 있으며, int가 훨씬 큰 표현 범위를 갖고 있습니다. 

byte -> int                                                                                                                   
                                         /00001010(byte)                                                                   
00000000/00000000/00000000/00001010(int)         10진수        값손실 없음                          

int -> byte                                                                                                                   
00000000/00000000/00000000/00001010(int)                                                                      
                                         /00001010(byte)      10진수        값손실 있음                          

위의 그림과 같이 byte값을 int값으로 변환하는 것은 1byte에서 4byte로 나머지 3byte(24자리)를 단순히 0으로 채워주면 되므로 기존의 값이 그대로 보존이 됩니다. 하지만 int값을 byte값으로 변환하는 것은 1byte에서 4byte로 나머지3 byte(24)를 잘라내서 1byte로 만드는 것이므로 기존의 int값이 보존될 수도 없을 수도 있습니다.

1byte         2byte        4byte      8byte        4byte          8byte                                          
 byte   ->   short   ->   int   ->   long   ->   float   ->   double                                         
                  char   ->   int                                                                                             

현변환이 가능한 7개의 기본형을 왼쪽부터 오른쪽으로 표현할 수 있는 값의 범위가 작은 것부터 큰 것의 순서로 나열한 것이다. 왼쪽에서 오른쪽으로의 변환은 캐스트 연산자를 사용하지 않아도 자동형변환이 되며, 그 반대 방향으로의 변환은 반드시 캐스트 연산자를 이용한 형변환을 해야합니다.
 보통 자료형의 크기가 클 수록 값의 표현범위가 크지만, 실수형은 정수형과 다르게 값을 표현하기 때문에 같은 크기형이라도 정수형보다 실수형이 훨씬 더 큰 표현범위를 갖습니다. 따라서 float와 double형이 int와 long형보다 오른족에 위치합니다.
 char와 short는 둘 다 2byte의 크기로 크기가 같지만 char형의 범위는 0~2^16-1(0~65535)이고 short의 범위는 -2^15~2^15-1(-32768~32767)이므로 서로 범위가 달라 둘 중 어느쪽으로 형변환을 하여도 값 손실이 발생할 수 있으므로, 자동적으로 형변환이 수행되지 않습니다.

boolean형을 제외한 나머지 기본형은 서로 형변환이 가능합니다.
기본형과 참조형은 서로 형변환을 할 수 없습니다.
서로 다른 타입의 변수간의 연산은 형변환을 하는 것이 원칙이지만, 값의 범위가 작은 타입에서 큰 타입으로의 형변환은 생략할 수 있습니다.

댓글 없음:

댓글 쓰기