[java] 형변환의 주의점과 문제점

자바에서 형 변환은 데이터의 타입을 서로 다른 타입으로 변경하는 작업입니다. 하지만 형 변환은 주의를 요구하며, 일부 문제가 발생할 수 있습니다. 이번 글에서는 자바에서 형 변환을 사용할 때 주의해야 할 점과 발생할 수 있는 문제점에 대해 살펴보겠습니다.

1. 손실이 있는 형 변환

먼저, 형 변환 과정에서 데이터가 손실될 수 있다는 점을 유의해야 합니다. 예를 들어, double 타입의 데이터를 int 타입으로 변환하는 경우 소수점 이하의 데이터는 사라집니다. 따라서 데이터의 손실 여부를 고려하여 형 변환을 수행해야 합니다.

다음은 double 타입에서 int 타입으로 형 변환하는 예시 코드입니다.

double d = 3.7;
int i = (int) d;
System.out.println(i); // 3

위 예시에서 double 타입인 dint 타입으로 형 변환하면서 데이터가 손실되어 3이 출력됩니다.

2. 오버플로우와 언더플로우

형 변환 과정에서 데이터의 크기가 범위를 벗어나는 경우 문제가 발생할 수 있습니다. 이를 오버플로우(overflow) 혹은 언더플로우(underflow)라고 합니다.

예를 들어, int 타입의 최대 값인 2,147,483,647을 초과하는 값을 int 타입으로 변환하는 경우 오버플로우가 발생하며, 음수 값으로 변환될 수 있습니다.

다음은 오버플로우가 발생하는 예시 코드입니다.

int i = 2147483647;
i = i + 1;
System.out.println(i); // -2147483648

위 예시에서 int 타입의 최대 값인 2,147,483,647에 1을 더하면 오버플로우가 발생하여 -2,147,483,648이 출력됩니다.

3. 클래스간의 형 변환

자바에서는 클래스간에도 형 변환이 가능합니다. 하지만 이 때 발생할 수 있는 문제점이 있습니다. 형 변환을 수행하기 전에 해당 클래스가 상속 관계에 있는지 확인하고, 명시적인 형 변환인지 암묵적인 형 변환인지 구분하여 사용해야 합니다.

다음은 클래스 간 형 변환에서 발생할 수 있는 문제와 그 해결 방법을 보여주는 예시 코드입니다.

class Animal {
    public void eat() {
        System.out.println("Animal is eating");
    }
}

class Dog extends Animal {
    public void eat() {
        System.out.println("Dog is eating");
    }
    
    public void bark() {
        System.out.println("Dog is barking");
    }
}

class Cat extends Animal {
    public void eat() {
        System.out.println("Cat is eating");
    }
    
    public void meow() {
        System.out.println("Cat is meowing");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal = new Dog();
        animal.eat(); // Dog is eating
        animal.bark(); // Error: Animal 타입에는 bark() 메소드가 없음
        
        Dog dog = (Dog) animal;
        dog.bark(); // Dog is barking
    }
}

위 예시에서 Dog 클래스는 Animal 클래스를 상속받은 자식 클래스입니다. Animal 타입의 변수에 Dog 인스턴스를 할당한 후에 bark() 메소드를 호출하면 오류가 발생합니다. 이는 암묵적인 형 변환이 아니기 때문입니다. 따라서 명시적인 형 변환을 통해 Dog 타입으로 형 변환을 수행한 후에 bark() 메소드를 호출해야 합니다.

참고 문서