경계 유형 : 여러 경계
-
21-12-2019 - |
문제
이 기사를 읽었습니다. 여기 바인딩 된 유형으로 작동하는 방법. 내가 얻으려고하는 것은 네 가지 사례를 처리하는 매개 변수화 된 방법입니다.
- t는 B만을 확장
- t가 B와 i (여기서 d)
- t는 i 만 를 확장합니다.
- 모든 것
여기서 코드가 있습니다.
public class Main {
public static void main(String... args) {
B b = new B();
D d = new D();
I i = new I() {
};
handle("aaasd");
handle(b);
handle(d); <---- Problem 1
handle(i);
}
public static class B {
}
public static interface I {
}
public static class D extends B implements I {
}
public static <T> void handle(T objT) {
System.out.println("T");
}
private static <T extends B> void handle(T obj) {
System.out.println("B");
}
public static <T extends B & I> void handle(T objT) { <--- Problem 2
System.out.println("B+I");
}
private static <T extends I> void handle(T obj) {
System.out.println("I");
}
}
.
컴파일러는 두 가지를 불평하고 다음과 같이 말합니다.
-
모호한 호출
메서드 핸들 (main.d)은 유형의 메인에 모호합니다. 나는 문제가 문제 번호 2와 같은 원인으로 인해 발생하는 것 같아 & 나는 분명히 T의 유형을 b의 아형에 명확하게 경계시켜 내 의견으로 모호성을 제거합니다.
-
동일한 소거 핸들
방법 핸들 (t)은 유형의 다른 방법으로 동일한 지우개 핸들 (main.b)을 갖는다. 내 추측은 이것이 모든 문제의 실제 원인이라는 것입니다. 자바는 어떻게 든 런타임 중에 내가 경계를 제거합니까? 그러나 B 유형으로 메소드를 호출하면 agoted 메소드를 호출하지 않습니다.
누군가가 B, B & I 및 I을 구별하는 방법을 설명 할 수 있습니까?
해결책
Java의 모든 제네릭에 적용되는 유형 삭제라는 개념이 있습니다.일반 메소드를 사용하여 편집 후 바이트 코드의 메소드가 삭제로 나타납니다. 그래서
public static <T> void handle(T objT) {
System.out.println("T");
}
private static <T extends B> void handle(T obj) {
System.out.println("B");
}
public static <T extends B & I> void handle(T objT) { <--- Problem 2
System.out.println("B+I");
}
private static <T extends I> void handle(T obj) {
System.out.println("I");
}
.
실제로
가됩니다public static void handle(Object objT) {
System.out.println("T");
}
private static void handle(B obj) {
System.out.println("B");
}
public static void handle(B objT) {
System.out.println("B+I");
}
private static void handle(I obj) {
System.out.println("I");
}
.
타입 변수의 왼쪽 가장 왼쪽은 해당 유형의 매개 변수가 바뀌는 것입니다.볼 수 있듯이 두 번째 및 3 번째 방법 모두 동일한 이름과 동일한 매개 변수 유형이 동일합니다.같은 서명.컴파일러가 허용 할 수 없습니다.
그러나 경계의 구문은 인터페이스 유형이므로 모든 인터페이스 유형 이전에 클래스 유형을 제공하도록 강제합니다.
<T extends I & B>
.
가 작동하지 않습니다.또한 4 번째 방법이 다시 동일한 지우개가 있기 때문에 작동하지 않습니다.
추가로 호출
handle(d);
.
는 제 2 및 4 번째 방법이 처리 할 수 있기 때문에 문제가 있지만, 아무도 더 구체적으로 존재하지 않습니다.이것은 과부하 모호함으로 알려져 있습니다.
다른 팁
Java는 런타임 중에 I로 경계를 제거합니까?
아니오, Java는 런타임 (반영 목적을 제외하고) 유형 정보를 런타임에 모든 유형 정보를 제거합니다.
경계를 사용하여 컴파일러는 코드를 handle(Object)
, handle(B)
및 handle(I)
및 T extends B & I
에 대한 코드를 변환 할 수 있지만 컴파일러가 충돌을 가져올 수 있습니다.
afaik, 공통된 바운드를 가지지 않고이 문제를 해결할 수있는 방법은 없습니다.T extends D
대신 T extends B & I
대신 D extends B implements I
또는 메소드 이름을 변경하거나 다른 매개 변수를 추가 할 수 있습니다.
다른 방법은 B + I 케이스에 B + i 케이스에 로직을 추가하고 내부의 두 번째 조건을 확인하는 것일 수 있습니다.
private static <T extends B> void handle(T obj) {
if( obj instanceof I) {
System.out.println("B+I");
}
else {
System.out.println("B");
}
}
.