2014-12-25 4 views
13

아래 1 행의 코드를 잘 모르겠습니다.구현되지 않은 인터페이스 컴파일로 캐스팅

interface Talkable{ } 
class Device{} 
class Phone extends Device implements Talkable{} 


Talkable d = (Talkable) new Device(); //line 1 
Talkable p = new Phone(); //line 2 

Phone은 Talkable을 구현했기 때문에 line2를 이해하지만 Device and Talkable은 관련이 없습니다. line1은 어떻게 합법적 일 수 있습니까?

답변

9

사실, 자바는 완벽하게 유효한이 (주조는 거의 의미가 경우에도) 다른 하나 개 관련 유형 캐스팅하는 것입니다. 형식이 과 호환되지 않으면 일 때 런타임 중에 오류가 발생합니다.

예를 들어

:

public static void main(String[] args) { 
     String s = (String) new Object(); 
     System.out.println(s.intern()); 

    } 

잘 컴파일되지만 런타임 예외가 발생합니다 런타임

+0

흠, 나는 그것을 몰랐다. 그래서, Phone이 Device를 확장하지 않았다고해도, 라인 1은 여전히 ​​컴파일러를 통과 할 것입니까? – user1529412

+0

@ user1529412 - 네. 맞아 .. 내 편집을 확인하십시오 :) – TheLostMind

+1

'(Number) ""'가 실패하는 이유는 무엇입니까? – August

5

라인 1시 Exception in thread "main" java.lang.ClassCastException: java.lang.Object cannot be cast to java.lang.String at Sample.main(Sample.java:5)을 제공합니다. 컴파일러는 캐스트가 성공적으로 완료 될 수 있는지 컴파일 타임에 확인하지 않습니다. 이러한 이유로 먼저 instanceof 연산자를 사용하여 이것을 확인하는 것이 좋습니다. 일반적으로

, 당신은 항상 클래스 B extends A implements C, 또는 B implements A, C

같은 클래스가 존재 할 수 있기 때문에 클래스의 변수 x 주조 사실이 아니다, 어떤 인터페이스 C에 유형 A의 변수 x 전송할 수 있습니다 A을 임의의 클래스 D으로 바꾸는 것은 서브 클래스 E extends A, D이 존재할 수 없기 때문에 클래스가 여러 클래스를 확장 할 수 없기 때문입니다.

18

컴파일러 이것은 JLS section 5.5.1 (굵게 관련 부분)에서 설명 받아 그 이유

컴파일 시간 기준 타입 S (소스) 및 컴파일 시간 기준 타입 T (목표)를 감안할 다음 규칙으로 인해 컴파일 타임 오류가 발생하지 않으면 S부터 T 로의 형 변환이 존재합니다.

S 클래스 유형 인 경우 :

  • T 다음, 클래스 타입 인 경우 중 | S | < : | T | 또는 | T | < : | S |. 그렇지 않으면 컴파일 타임 오류가 발생합니다.

또한 X의 상위 유형 X와 S의 상위 유형 Y가있는 경우 X와 Y가 명확하게 구분 된 매개 변수 유형 (§4.5)이고 X 및 Y의 지우기가 같은 경우 컴파일 타임 오류가 발생합니다.

  • T가 인터페이스 타입 인 경우 T의 수퍼 타입 ​​X가 존재하는 경우

    는 S가 다음, 최종 클래스 (§8.1.1) 아니다
    • 경우, 그리고 퍼 X와 Y가 서로 다른 매개 변수화 된 형식이고 X와 Y의 지우기가 같으면 S의 Y는 컴파일 타임 오류가 발생합니다.

      그렇지 않으면 S는 T를 구현하지 않아도 S의 하위 클래스가 될 수 있으므로 항상 컴파일 타임에 유효합니다. DeviceTalkable로 변환 할 수 없기 때문에 귀하의 경우에는

이하는 java.lang.ClassCastException 런타임에 발생합니다. 그러나 프로그램이 실행될 때까지 을 구현하는 Device의 하위 클래스가있을 수 있으므로 컴파일러는 캐스트를 허용합니다.

3

실제적으로 코드는 컴파일러에서 오른쪽에있는 객체가 왼쪽에있는 객체 유형 ("type casting"임)임을 명시 적으로 "알립니다". 이것은 컴파일 타임에 Java의 두 가지 유형 모두에 유효하지만, 유형이 관련이없는 경우 런타임 오류가 발생합니다 (Exception이 발생합니다). Phone는 전화가 Talkable (그리고 Device), 그래서 실제로, 그것은 및/또는 구현을 확장 어떤 타입이기 때문에 수행되는 정도 선 두에

는 컴파일 타임 및 런타임에서 유효합니다.

관련 문제