다형성의 java.lang.ClassCastException: cannot be cast to 에러, instanceof의 Incompatible conditional operand types에러 해결법

다형을 이용한 예제

  • s의 데이터 타입이 Sub1이면 ‘Sub1’출력하고 아니면 ‘Sub2’를 출력하는 코드예시이다.
  • 다형성을 이용한 형변환으로 변수s을 다운캐스팅(Super -> Sub1)했다
  • 원하는 결과값이 잘 출력되었다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Super{}
class Sub1 extends Super {}
class Sub2 extends Super {}

public class question24 {

public static void main(String[] args) {
Super sup = new Sub1();
Sub1 s = (Sub1) sup;

if( s instanceof Sub1){
System.out.println("Sub1");
}else{
System.out.println("Sub2");
}
}
}
//출력값
Sub1




Incompatible conditional operand types 에러 발생

  • Sub2도 만들어보고싶어서 아래와 같이 코드를 추가했는데 Exception in thread "main" java.lang.Error: Unresolved compilation problem 컴파일 에러가 났다.
  • 직역하면 호환되지 않는 조건부 피연산자 유형에러이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Super{}
class Sub1 extends Super {}
class Sub2 extends Super {}

public class question24 {

public static void main(String[] args) {
Super sup = new Sub1();
Sub1 s = (Sub1) sup;
Sub2 s2 = (Sub2) sup; //추가한 코드

if( s2 instanceof Sub1){
System.out.println("Sub1");
}else{
System.out.println("Sub2");
}
}
}
//출력값 : 에러
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Incompatible conditional operand types Sub2 and Sub1




Incompatible conditional operand types 에러 원인과 해결법

  • 해결을 위해서는 instanceof 연산자를 알아야한다.
  • instanceof 연산자는 A(Object) instanceof B(Class, Interface) 형태로 사용하고 return은 boolean이다.
  • 오브젝트 A를 클래스 B나 인터페이스 B로 casting가능유무(Boolean)를 확인한다.
  • 따라서 B가 클래스일 경우에는 A가 반드시 B 클래스와 상속관계에 있어야 true가 된다.
  • 만약 A와 B가 전혀 상호 상속관계가 없을 경우 캐스팅이 불가능 -> 컴파일 에러 발생.
  • 위의 예시에서 s2 instanceof Sub1에서 변수s(소속 : Sub2)와 Sub1(소속 : Sub1)은 상속관계 없기에 컴파일 에러가 발생했다.
  • 그래서 s2 instanceof Sub1에서 s2 instanceof Sub2로 바꾸어보았다.




java.lang.ClassCastException 에러 발생

  • s2 instanceof Sub1에서 s2 instanceof Sub2로 바꾸었더니 이번엔java.lang.ClassCastException에러가 발생했다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Super{}
class Sub1 extends Super {}
class Sub2 extends Super {}

public class question24 {

public static void main(String[] args) {
Super sup = new Sub1();
Sub1 s = (Sub1) sup;
Sub2 s2 = (Sub2) sup; //추가한 코드

if( s2 instanceof Sub2){
System.out.println("Sub2");
}else{
System.out.println("Sub1");
}

}
}
//출력값(예외에러)
Exception in thread "main" java.lang.ClassCastException: test1.Sub1 cannot be cast to test1.Sub2




java.lang.ClassCastException 에러 원인과 해결법

  • 다운캐스팅은 업캐스팅이 일어난 값에 한해서만 다운캐스팅이 가능하다.
  • 업캐스팅이 선행되지 않으면 다운캐스팅을 할 수 없다.
  • 참고링크 : DownCasting(다운캐스팅 = 명시적 형변환)
  • 따라서 Super sup2 = new Sub2();로 업캐스팅해준뒤 Sub2 s2 = (Sub2) sup2;로 다운캐스팅을 하면 원하는 출력값을 볼 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Super{}
class Sub1 extends Super {}
class Sub2 extends Super {}

public class question24 {

public static void main(String[] args) {
Super sup = new Sub1(); //업캐스팅
Sub1 s = (Sub1) sup; //다운캐스팅
Super sup2 = new Sub2(); //새로 추가한 코드(업캐스팅)
Sub2 s2 = (Sub2) sup2; //추가한 코드(다운캐스팅)

if( s2 instanceof Sub2){
System.out.println("Sub2");
}else{
System.out.println("Sub1");
}
}
}
//출력값
Sub2