2013-06-13 1 views
4

한다고 가정 나는 다음과 같은 클래스가 :제네릭 형식의 추론이 여기서 작동하지 않는 이유는 무엇입니까?

public class STTest { 

    @Test 
    public void test() throws Exception { 
    createInstance(MyTImpl.class); 
    } 

    public static<T extends MyT<S, T>, S extends MyS<T, S>> void createInstance(
     final Class<? extends MyT<S, T>> beanClass) throws Exception { 

    final MyT<S, T> bean = beanClass.newInstance(); 
    } 
} 

확인을 잘 :

interface MyS<T extends MyT<S, T>, S extends MyS<T, S>> { 
} 
interface MyT<S extends MyS<T, S>, T extends MyT<S, T>> { 
} 
public class MySImpl implements MyS<MyTImpl, MySImpl> { 
} 
public class MyTImpl implements MyT<MySImpl, MyTImpl> { 
} 

내가 경고없이 컴파일하고 성공적으로 실행되는 테스트 케이스를 다음 구축 할 수 있습니다.

invalid inferred types for S; inferred type does not conform to declared bound(s) inferred: MySImpl bound(s): MyS

왜 이것이다 :

public class STTest { 

    @Test 
    public void test() throws Exception { 
    createInstance(MyTImpl.class); 
    } 

    public static<T extends MyT<S, T>, S extends MyS<T, S>> void createInstance(
     final Class<T> beanClass) throws Exception { 

    final T bean = beanClass.newInstance(); 
    } 
} 

그러나,이 컴파일 오류입니다 :하지만이 동일한 영향을 미칠 것으로 예상?

는 UPDATE :

나는 행동이 컴파일러에 의존하는 것으로 나타났습니다. 코드 컴파일을 위해 OpenJDK 1.6 컴파일러 (javac 1.6.0_27)를 사용했습니다. 그리고 그것은 부서집니다. 그러나 :

  • 오픈 JDK 1.7 컴파일러 (javac의 1.7.0_21) 및
  • 오라클 1.6 컴파일러 (javac의 1.6.0_37)

두 번째 예에서 모두 잘 작동.

그러나 이것은 OpenJDK 1.6 컴파일러의 버그입니까? 아니면 Java 언어 사양의 모호성입니까?

+3

코드를 실행할 수 있으며 컴파일 오류가 발생하지 않습니다. – darijan

+0

여기에 있습니다. 인터페이스 선언시 괄호가 누락 된 경우에만 컴파일 오류가 발생합니다. –

+0

Java 7 용 Eclipse 컴파일러와 함께 컴파일되도록 추가하겠습니다. –

답변

3

인수 유형에는 두 번째 예제에서 S가 어떤 식 으로든 언급되지 않습니다. 컴파일러는 따라서 그것을 추론 할 수 없다는 것을 알려줍니다.

자세히 설명합니다. 첫 번째 예에서는 Class<? extends MyT<S, T>>을 요청합니다. test()Class<MyTImpl>을 입력하십시오. 컴파일러가 범위를 확인하면 MyTImpl에 대해 을 일치시키고 MyTImplMyT<MySImpl, MyTImpl>을 구현하므로 의 경우 MySImpl이고 MyTImpl의 경우 T 인 경우 두 가지를 나란히 놓기 만하면됩니다.

ST의 제약 조건을 MySImplMyTImpl으로 확인합니다.이 제약 조건은 성공합니다.

두 번째 예에서는 Class<T>을 요청합니다. 컴파일러는 Class<MyTImpl>을보고 에 대해 MyTImpl을 유추하며 완료됩니다. S을 유추하지 못하면 오류가 발생합니다.

어떤 정보를 제공 할 수있는 T에 대한 제한 검사가 발생하지 않습니다. S.

+1

사실, 이것은 일어나지 않습니다. 하지만 왜? 그 동안 나는 그 행동이 컴파일러에 의존한다는 것을 알아 냈습니다. 그래서 분명히 가능합니다. – yankee

관련 문제