27

이 코드는 Java 8에서는 컴파일되지만 Java 7에서는 컴파일되지 않습니다.

class Map<K,V> {
    static <K,V> Map<K,V> empty() {return null;}
    Map<K,V> put(K k, V v) {return null;}
    V get(K k) {return null;}
}

class A {
    static void f(Map<Integer,String> m){}
    public static void main(String[] args) {
        f(Map.empty());
    }
}

구체적인 유형을 추측하지는 않습니다.Map에서 돌아온Map.empty():

$ javac7 A.java
A.java:10: error: method f in class A cannot be applied to given types;
        f(Map.empty());
        ^
  required: Map<Integer,String>
  found: Map<Object,Object>
  reason: actual argument Map<Object,Object> cannot be converted to Map<Integer,String> by method invocation conversion
1 error

변경하면 컴파일됩니다.f~에게 전화 해f(Map.<Integer,String>empty());. Java 8에서는이 기능을 사용하지 않고도 작동합니다.

그러나 당신이f~에게 전화 해f(Map.empty().put(1,"A").put(2,"B"));, Java 7과 8 모두에서 다시 컴파일되지 않습니다. 왜?

$ $javac7 A.java 
A.java:10: error: method f in class A cannot be applied to given types;
        f(Map.empty().put(1,"A").put(2,"B"));
        ^
  required: Map<Integer,String>
  found: Map<Object,Object>
  reason: actual argument Map<Object,Object> cannot be converted to Map<Integer,String> by method invocation conversion
1 error

$ $javac8 A.java
A.java:10: error: incompatible types: Map<Object,Object> cannot be converted to Map<Integer,String>
        f(Map.empty().put(1,"A").put(2,"B"));
                                    ^
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
1 error

$ $javac8 -Xdiags:verbose A.java
A.java:10: error: method f in class A cannot be applied to given types;
        f(Map.empty().put(1,"A").put(2,"B"));
        ^
  required: Map<Integer,String>
  found: Map<Object,Object>
  reason: argument mismatch; Map<Object,Object> cannot be converted to Map<Integer,String>
1 error


  • 그냥 만드세요.static Map empty() {return null;}어쨌든 제네릭을 사용하는 수정자를 추가하는 것과 다릅니다. - ug_

1 답변


31

왜 ?

제네릭 형식의 형식 유추가 체인 된 호출로 확장되지 않았기 때문입니다.

로부터제네릭 형식 유추에 대한 자바 자습서:

목표 유형이 무엇인지 개념은 메소드 인수를 포함하도록 확장되었습니다.

이것이 바로이 코드입니다.

f(Map.empty());

컴파일합니다.

그러나이 코드는 체인화 된 호출이기 때문에 그렇지 않습니다.

f(Map.empty().put(1,"A").put(2,"B"));

작은 단락을 찾을 수도 있습니다.JSR-000335 평가 용 JavaTM 프로그래밍 언어 최종 릴리스 용 람다 식(구체적으로 D 부) :

a (). b ()에서 b의 호출에서 유형 정보를 호출하여 a의 호출로 전달하는 추론을 허용하는 데 관심이 있습니다. 이는 부분 정보가 양방향으로 전달되어야하므로 추론 알고리즘의 복잡성에 또 다른 차원을 추가합니다. 모든 인스턴스 (예 : List)에 대해 a ()의 반환 유형 삭제가 고정 된 경우에만 작동합니다. 목표 유형을 쉽게 도출 할 수 없으므로이 기능은 폴리 표현 모델에 적합하지 않습니다. 향후 추가 될 수있는 추가 기능이 추가 된 것입니다.

아마 Java 9에서.

연결된 질문


관련된 질문

최근 질문