시소당
instanceof 가 객체 reference 타입과 class를 비교해서 reference타입이 Class타입과 같으면 true 틀리면 false를 리턴해주는 연산자로 알고있는데요...
class Point { int x, y; }
class Element { int atomicNumber; }
class Test {
public static void main(String[] args) {
Point p = new Point();
Element e = new Element();
if (e instanceof Point) { // compile-time error
System.out.println("I get your point!");
}
}
}
이렇게 하면 컴파일시 에러가 나고
class Point extends Element{ int x, y; }
class Element { int atomicNumber; }
class Test {
public static void main(String[] args) {
Point p = new Point();
Element e = new Element();
if (e instanceof Point) {
System.out.println("I get your point!");
}
}
}
이렇게 하면 컴파일시 에러가 안나고 잘 되요...
두개의 소스의 차이점이 뭔가요?
제생각에는 위에 있는 소스는 e가 Element 타입이고 Point는 Point이니깐 false가 되어서 컴파일이 될 것 같은데...말이죠
좀 자세히 설명해주시면 감사요^^
---------------------------------------------------------------------------------------------------
instanceof 연산자를 설명하면..
A(Object) instanceof B(Class, Interface) 형태로 사용합니다.
즉 A위치에는 Object가 오구요, B 위치에는 클래스 나 인터페이스가 옵니다.
이때 instanceof 연산자는 A Object를 B 클래스나 인터페이스로
캐스팅이 가능한것인지를 확인하는 연산자입니다.
따라서 B가 클래스일 경우에는 A 가 반드시 B 클래스와 상속관계에 있어야만 유효하게 됩니다.
A와 B가 전혀 상호 상속관계가 없을 경우 캐스팅이 불가능하기에 컴파일 타임에 에러를 발생시킵니다.
왜 에러가 나냐면 instanceof 가 upcast 여부를 판단하는 연산자이기에 내부적으로
캐스팅 처리를 해야하기 때문입니다.
따라서 아래처럼 Point와 Element 둘이 상속관계가 아닐 경우 아래처럼 코딩하면 당연히 에러가 나죠.
Point p = new Point();
Element e = (Element) p; <-- 여기서 캐스팅 불가능하다고 에러납니다.
false가 되지 않고 에러가 나는 내부적인 이유는 이와같이 캐스팅에 대한 컴파일 에러때문이라 할수 있습니다.
그런데... 여기서 참고로... 만약 B 가 인터페이스라면 에러가 안납니다.
참고로 List 라는 인터페이스가 있을때...
Point p = new Point();
List e = (List) p; <-- 이건 컴파일 타임에 에러가 나지 않습니다. 런타임에 에러가 나죠.
즉 Interface에 대한 캐스팅 에러는 컴파일타임에 체크하지 않는다는 것이지요.
좀 부연설명까지 해서 어렵게 설명이 된지 모르겠습니다만,, 암튼 이걸로 답변은 되었으리라 기대합니다.
[2008년 03월 03일 18:02:21 수정되었습니다.]