1 minute read

Updated:

참조변수의 형변환

  • 참고하고 있는 인스턴스에서 사용할 수 있는 멤버의 갯수를 조절하는 것.
  • 조상-자손 관계일때만 서로 형변환이 가능함.
  • 캐스트연산자를 사용하며, 괄호()안에 변환하고자 하는 타입의 이름(클래스명)을 적어주면 된다.
class Car {
    String color;
    int door;
    void drive() {      // 운전하는 기능
        System.out.println("drive, Brrrr~");
    }
    void stop() {       // 멈추는 기능
        System.out.println("stop!!!");
    }
}
class FireEngine extends Car {  // 소방차
    void water() {              // 물 뿌리는 기능
        System.out.println("water!!!");
    }
}
class Ambulance extends Car {   // 앰뷸런스
    void siren() {              // 사이렌을 울리는 기능
        System.out.prinln("siren~~");
    }
}
Car car = null;
FireEngine fe = new FireEngine();
FireEngine fe2 = null;

car = fe;                       // car = (Car)fe;에서 형변환 생략됨. 업캐스팅
fe2 -  (FireEngine)car;         // 형변환을 생략불가. 다운 캐스팅

형변환 생략가능과 생략불가능한 경우

자손타입 -> 조상타입(업캐스팅) : 형변환 생략가능 </br> 조상타입 -> 자손타입(다운캐스팅) : 형변환 생략불가

  • 업캐스팅의 경우, 참조변수가 다룰 수 있는 멤버의 개수가 실제 인스턴스가 갖고 있는 멤버의 개수보다 적거나 같을 것이 분명하기 때문에 형변환이 생략 가능함.

형변환 오류가 발생하는 경우(ClassCastException)

class CastingTest2 {
    public static void main(String args[]) {
        Car car = new Car();
        Car car =  null;
        FireEngine fe = null;
        
        car.drive();
        fe = (FireEngine)car;
        fe.drive();
        car2 = fe;
        car2.drive();
    }
}

실행결과
drive,  Brrrr~
java.lang.ClassCastException: Car at CastingTest2.main(CastingTest2.java:8)
  • 컴파일은 성공하지만 실행 시 에러가 발생한다.
  • 참조변수 car가 참조하고 있는 인스턴스가 Car타입(조상)이기 때문이다. 즉, 조상타입의 인스턴스를 자손타입의 참조변수로 참조하는 경우, 참조변수의 멤버가 인스턴스(객체) 멤버 갯수보다 많아 존재하지 않는 멤버를 사용할 가능성이 있으므로 형변환이 허용되지 않는다.
  • 따라서 참조변수가 가리키는 인스턴의 타입이 무엇인지(실제 객체의 멤버 갯수) 확인하는 것이 중요하다.

instanceof연산자

  • 참조변수의 형변환 가능여부를 확인하는데 사용한다. instanceof연산의 결과가 true이면 해당 타입으로 형변환이 가능하다.
  • 주로 조건문에 사용되며 instanceof의 왼쪽에는 참조변수, 오른쪽에는 타입(클래스명)이 피연산자로 위치한다.
  • instanceof연산자는 자기 자신, 조상까지 true를 반환한다.
class InstanceofTest {
    public staic void main(String args[]) {
        FireEngine fe = new FireEngine();
        
        if(fe instanceof FireEngine) {
            System.out.println("This is a FireEngine instance.");
        }
        
        if(fe instanceof Car) {     
            System.out.println("This is a Car instance.");
        } //fe의 인스턴스타입이 Car가 아님에도 true인 것은 Car타입(조상타입)으로 형변환이 가능하다는 것을 뜻한다.
          //따라서 실제 인스턴스 타입을 알려주는 것이 아니다.
        
        if(fe instanceof Object) {
            System.out.println("This is a Object instance.");
        }
        
        System.out.println(fe.getClass().getName());    // 클래스의 이름을 출력
    }
}
class Car { }
class FireEngine extends Car { }

// 실행결과 
        This is a FireEngine instance.
        This is a Car instance.
        This is a Object instance.

Tags:

Categories:

Updated: