Master_Worm 2021. 3. 18. 00:35

   형변환이란? 리터럴과 변수에는 기본적으로 타입이 있다. (정수형, 실수형, 문자형 등등) 하지만 프로그래밍을 하다보면 서로 다른 타입 간에 연산이 필요한 경우가 있다. 그래서 이러한 경우 타입을 변환해줘야 하는 경우가 생기는데, 이러한 경우에 행하는 연산을 형변환이라 한다. (타입을 일치시키기 타입을 변환시키는 것을 형변환이라 한다.)

 

   자바 컴파일러는 자동으로 형변환을 해줌으로써 프로그램을 자연스럽게 동작하게끔 만들어준다. 실상 형변환은 프로그래머가 신경써야 하는 일 중 하나지만, 그렇지 못할 경우 자동 형변환을 함으로써 편하게 만들어주지만, 이러한 편함 속에는 논리적 오류가 생기기 마련이다. 

 

그래서 이러한 형변환에 대해 간략하게 알아보도록 하자.

 

1. 형변환하는 방법


기본적인 형변환은 별로 어렵지 않다. 단순히 변수나 리터럴 앞에 변환하고자 하는 타입을 괄호 안에 넣어서 써주기만 하면 된다. 

int a = 10;
double b = (double)a;

int 타입의 a라는 변수를 double의 형변환을 한 뒤에 b에 할당하는 것이다. 

 

class Main {
    public static void main(String[] args) {
        int a = 10;
        double b = (double)a;

        System.out.println(a);
        System.out.println(b);
    }
}

실제로 출력을 해보면 출력 결과로 

10
10.0

으로 나오는 것을 확인할 수 있다. 정상적으로 형변환 됨을 확인가능하며, 형변환이 이루어진 int a는 형변환이 이루어지고 값이 할당된 뒤에는 값의 변화가 없는 것을 확인할 수 있다. (여전히 int형이다.)

 

기본적으로 형변환은 boolean을 제외한 나머지 타입들은 서로 형변환이 가능하다. 하지만 주의할 점이 있다. 실수형과 정수형에서는 기본적인 데이터를 표현하는 방법 자체가 다르기 때문에 데이터 손실이 발생할 수 있다.

 

2. 타입별 형변환


타입별 형변환에서 주의할 점은 데이터의 손실 가능성이다. int 형은 32비트, byte형은 8비트이다. 그렇다면 int형에서 byte형으로 형변환이 일어나면 데이터 손실 가능성이 있는 것이다. 

 

실제로 코딩을 통해 실험해보도록 하자. 

 

class Main {
    public static void main(String[] args) {
        int a = 10;
        byte b = (byte)a;

        System.out.println(a);
        System.out.println(b);

        a = 500;
        b = (byte)a;

        System.out.println(a);
        System.out.println(b);
    }
}

이 코드의 결과값은

 

10
10
500
-12

이러한 형태로 나온다. 초기에 값인 10을 입력할 때는 int와 byte에서 데이터 손실이 일어나지 않았지만, 두번째 값에서는 손실이 일어나고 있다. 이는 byte의 값의 범위에서 벗어난 범위를 넣었기 때문에 원치 않는 출력이 나오고 있는 상태이다. [ byte의 범위는 -128 ~ 127까지이며, 이 범위를 넘어서면 우리가 생각하는 값과는 다른 의도치 않은 값이 나올 수 있다.]

 

데이터 형에 따른 조금 더 자세한 형변환은 나중에 다루도록 하겠다.

 

3. 자동형변환


기본 형 변환은 다음과 같은 순서로 이루어진다.

이러한 형변환이 만들어진 이유는 데이터의 손실이 없는 방향으로 형 변환이 이루어진다. 일반적으로 타입에 따른 범위 내에서는 자동형변환이 일어나지만 범위를 벗어나는 데이터를 할당하려고 하면 오류 메시지를 보내준다. 

* 기본형과 참조형은 서로 형변환이 불가능하다.

 

예를 들어,

byte a = 10000;

byte의 범위인 -128 ~ 127을 넘는 범위를 저장하게 되면 오류메시지를 보내준다. 

java: incompatible types: possible lossy conversion from int to byte 를 자바 컴파일러가 보내주며, 오류가 났다고 명시해준다. 하지만 여기서 명시적 형변환을 지시해주게 되면 오류가 나지 않는다. 

 

byte a = (byte)10000;

이렇게 컴파일하면 컴파일 오류가 나지 않는다. 프로그래머가 의도한 오버플로라 컴파일러가 판단하는 것이다. 

 

또 다른 경우는 연산 과정에서 형변환이 자동으로 일어난다. 연산에서는 범위가 조금 더 넓은 범위로 형변환해서 타입을 일치시킨 뒤 연산을 시행한다. (이렇게 하는 이유는 범위가 넓은 쪽으로 형변환해서 연산해야 데이터의 손실이 가장 적어지기 때문이다.)

 

int a = 10;
double b = 10.0 + a;

a는 int형이지만, 실제로 계산할 때는 a가 double형으로 형변환한 뒤에 계산한다. 

 

만약에 최댓값에 대해 기억이 안난다면,

int i = Integer.MAX_VALUE;

를 사용함으로써 최댓값을 확인할 수 있다.