2013-02-06 6 views
6

을 다시 컴파일하지 않고 인터페이스를 변경 I 이 구현 클래스

public abstract interface X 
{ 
    public abstract void f() throws java.io.IOException; 
} 


public class Y implements X 
{ 
    public void f() throws java.io.IOException 
    { 
     throw new java.ioIOException("Hello"); 
    } 

    public static void main(String [] args) 
    { 
     X x = new Y(); 
     try 
     { 
      x.f(); 
     } 
     catch (IOException e) 
     { 
      System.out.println("Caught"); 
     } 
    } 

} 

이 지금은 모두를 컴파일하고 다음과 같은 클래스가 X.classY.class 수 있습니다.

지금 나는 단지 X.java &을 다시 컴파일하면 무엇을, X는 내가 X & 모두 Y, Y의 컴파일 그러나

Y.java:4: f() in Y cannot implement f() in X; overridden method does not throw j 
ava.io.IOException 

실패 컴파일 경우가 분명히

public abstract interface X 
{ 
    public abstract void f(); 
} 

을 던졌습니다 제거 변경 이전 X.java로 컴파일 된 Y.class를 유지하십시오.

그런 경우 어떻게됩니까? 잘 정의되어 있습니까?

또는 정의되지 않은 카테고리에 해당합니까? 즉, 어떤 일이 발생할 수 있습니까?

전혀 보장이 있습니까? 즉, Windows에서 Java 1.6.32를 항상 실행하고 있다면 아무 문제가 없어도 괜찮습니까?

업데이트 : 일부 답변은 런타임에 IncompatibleClassChangeError이 나올 것이라고 말했기 때문에 업데이트되었습니다. 하지만 나는 그렇지 않습니다. 위에서 주어진

단계

1)는 X.java 및 Y.java 모두 컴파일한다. 실행 Y.

출력 :

2

잡았다) 변경 X.java이 (가) 발생 주석합니다. X.java를 다시 컴파일하십시오. Y.java를 다시 컴파일하지 마십시오.

실행 Y

출력 : 겁에 질린

내가 컴파일러

Windows 7에서 자바를 실행하고

javac 1.6.0_35 

런타임

java version "1.6.0_35" 
Java(TM) SE Runtime Environment (build 1.6.0_35-b10) 
Java HotSpot(TM) Client VM (build 20.10-b01, mixed mode, sharing) 
+0

1. 왜 당신은 시도하지 않습니까? 2. 구현 자의 "초과"throw가 컴파일 타임 오류 메시지를 발생 시킨다는 것을 말합니다. – TheBlastOne

+1

@ TheBlastOne 시도해 보았습니다. 그것은 잘 작동합니다. 당신이 내 게시물을 제대로 읽지 못했을 수 있습니다 - 컴파일 시간 오류는 Y를 다시 컴파일 할 경우에만 발생합니다. – user93353

답변

3

이 지금 Java에서는 제한 사항입니다. 현재 인터페이스를 확장하는 하위 인터페이스를 만들고 필요하다면 예외없이 메소드를 재정의하십시오. 일반적으로 이것은 "바이너리 변경"이라고하며 코드가 실행될 때 연결이 끊어지며 JLS에서 잘 정의되어 있습니다 (전체 챕터가 JLS 13이고 구체적으로는 JLS 13.5).

편집 : 추가 조사를 거친 후 잘못된 결과가 나타났습니다. JLS 13.4.21에서 :

기존의 바이너리 호환성을 아프게하지 않는 방법이나 생성자의 throws 절에

변경; 이 절은 컴파일시에만 점검됩니다.

그러나 확인한 예외가 본질적으로 런타임에 선택 취소 될 수 있음을 의미하므로이 작업을 수행하지 않는 것이 좋습니다.

+0

왜 downvote? – Brian

+0

Java 8 'default'는 여기서 도움이되지 않습니다. 예외를 제거하는 것이 새로운 메소드를 생성하는 것이 아닙니다. 인터페이스와 일치하지 않는 방식으로 기존 메소드를 변경합니다. –

+0

@StephenC 어쨌든 나는 완전히 틀렸고 내 편집을 참조하십시오. – Brian