parameter - java generic type extends




메서드는 다른 메서드와 동일한 삭제 기능을 가지고 있습니다. (4)

같은 클래스에있는 두 가지 방법을 사용하는 것이 합법적이지 않은 이유는 무엇입니까?

class Test{
   void add(Set<Integer> ii){}
   void add(Set<String> ss){}
}

compilation error

메소드 add (Set)는 Test 유형의 다른 메소드와 동일한 삭제 add (Set)를가집니다.

나는 그것을 해결할 수 있지만, 왜 javac이 이것을 좋아하지 않는지 궁금해하고있었습니다.

나는 많은 경우에있어서 그 두 가지 방법의 논리가 매우 유사하고 단일 한 것으로 대체 될 수 있음을 볼 수있다.

public void add(Set<?> set){}

방법이 있지만 항상 그런 것은 아닙니다.

이러한 인수를 사용하는 constructors 가 두 개인 경우에는 constructors 중 하나의 이름을 변경할 수 없기 때문에이 작업은 번거롭다.


Java 제네릭은 형식 지우기를 사용합니다. 꺾쇠 괄호 ( <Integer><String> )의 비트가 제거되므로 동일한 서명 (오류에 표시되는 add(Set) 이있는 두 개의 메서드가 표시됩니다. 런타임에서 각 경우에 사용할 것을 알 수 없으므로 허용되지 않습니다.

자바가 제네릭을 다룰 수 있다면, 당신은 이것을 할 수 있지만, 지금은 그렇지 않을 것입니다.


문제는 Set<Integer>Set<String> 이 실제로 JVM에서 Set 로 처리된다는 것입니다. Set (String 또는 Integer)의 유형을 선택하는 것은 컴파일러에서 사용하는 문법적 설탕 일뿐입니다. JVM은 Set<String>Set<Integer> 구분할 수 없습니다.


이것은 Java 제네릭이 유형 지우기 로 구현 되었기 때문입니다.

당신의 메소드는 컴파일 타임에 다음과 같이 변환 될 것입니다 :

메소드의 해석은 컴파일시에 발생 해, 형태 파라미터는 고려하지 않는다. ( 에릭슨의 대답 참조 )

void add(Set ii);
void add(Set ss);

두 메소드 모두 유형 매개 변수가없는 동일한 서명을 가지므로 오류가 발생합니다.


컴파일러가 Set (Integer)를 Set (Object)로 Java 바이트 코드로 변환 할 수 있습니다. 이 경우 Set (Integer)는 구문 검사를 위해 컴파일 단계에서만 사용됩니다.





generics