Java Generics-Bridge 방법?
Java Generics와 관련된 "브리지 방법"개념이라고하는 것이 한 지점에서 멈추고 계속 생각하게되었습니다.
Btw, 나는 그것이 바이트 코드 수준에서만 발생하고 우리가 사용할 수 있습니다.
하지만 Java 컴파일러에서 사용하는 "브리지 방법"의 개념을 알고 싶습니다.
이면에서 정확히 어떤 일이 발생하며 왜 사용 하는가?
예제에 대한 도움을 주시면 대단히 감사하겠습니다.
제네릭 클래스를 확장하거나 제네릭 인터페이스 (구체적인 유형 변수 사용)를 구현하는 클래스를 원시 유형으로 계속 사용할 수있는 메소드입니다.
소지 상상해.
public class MyComparator implements Comparator<Integer> {
public int compare(Integer a, Integer b) {
//
}
}
Object
유형이 비교 방법으로 전달되기 때문에 비교를 위해 두 개의 전달하는 형식으로 사용할 수 없습니다 (일반 유형의 매개 변수 T에서 유형이 지워지는 것과는 동일합니다). 대신, 컴파일러는 배후에서 다음과 같은 "브리지 메소드"를 추가합니다 (Java 소스 임).
public class MyComparator implements Comparator<Integer> {
public int compare(Integer a, Integer b) {
//
}
//THIS is a "bridge method"
public int compare(Object a, Object b) {
return compare((Integer)a, (Integer)b);
}
}
컴파일러는 브리지 메서드에 대한 액세스를 보호하여 발생 시간 오류를 발생 명시 적 호출을 적용합니다. 이제 클래스를 원시 형식으로 사용할 수 있습니다.
Object a = 5;
Object b = 6;
Comparator rawComp = new MyComparator();
int comp = rawComp.compare(a, b);
다른 이유는 무엇입니까?
원시 유형 (주로 이전 버전과의 회선을 위해)의 명시 적 사용에 대한 지원을 추가하는 것 외에도 유형 삭제를 지원하기 위해 브리지 메소드가 필요합니다. 유형 삭제를 사용하면 다음과 같은 방법이 있습니다.
public <T> T max(List<T> list, Comparator<T> comp) {
T biggestSoFar = list.get(0);
for ( T t : list ) {
if (comp.compare(t, biggestSoFar) > 0) {
biggestSoFar = t;
}
}
return biggestSoFar;
}
실제로 다음과 호환되는 바이트 코드로 실행됩니다.
public Object max(List list, Comparator comp) {
Object biggestSoFar = list.get(0);
for ( Object t : list ) {
if (comp.compare(t, biggestSoFar) > 0) { //IMPORTANT
biggestSoFar = t;
}
}
return biggestSoFar;
}
브리지 메서드가 존재하지 않고이 함수에 a List<Integer>
및 a MyComparator
를 전달하면 태그 IMPORTANT
가 지정된 줄의 호출 이 실패합니다. 왜냐하면 2 초를받는 MyComparator
메서드가 호출되지 않았기 때문 입니다 .compare
Object
Integer
아래 FAQ는 좋은 읽기입니다.
또한보십시오:
브리지 방법이 필요한 이유를 이해하려면 방법 없이는 어떤 일이 발생하는지 더 잘 이해해야합니다. 브리지 방법이 없다고 가정합니다.
class A<T>{
private T value;
public void set(T newVal){
value=newVal
}
}
class B extends A<String>{
public void set(String newVal){
System.out.println(newVal);
super.set(newVal);
}
}
삭제 후 Type 매개 변수에 바인딩이 없기 때문에 set
in 메서드 가 A
되었습니다 . 클래스있는 방법이 없습니다 과 동일한 서명이있는 에가 . 따라서 재정의가 없습니다. 따라서 이와 같은 일이 발생했을 때 :public void set(Object newVal)
T
B
set
A
A a=new B();
a.set("Hello World!");
여기서 다형성은 작동하지 않습니다. 부모 클래스 var를 사용하여 다형성을 트리거 할 수 있도록 자식 클래스의 부모 클래스 메서드를 재정의해야합니다.
브리지 메서드가하는 일은 이름은 같지만 서명이 다른 메서드의 모든 정보로 부모 클래스의 메서드를 자동으로 재정의하는 것입니다. 브리지 방법의 도움으로 다형성이 작동했습니다. 표면적으로는 부모 클래스 메서드를 다른 서명의 메서드로 재정의합니다.
컴파일러가 그 방법을 추론 한다는 점은 흥미 롭습니다 MyComparator
.
public int compare(Integer a, Integer b) {/* code */}
무시하려고하고 Comparator<T>
의
public int compare(T a, T b);
선언 된 유형에서 Comparator<Integer>
. 그렇지 않으면 컴파일러 에서 MyComparator
's compare
는 재정의가 아닌 추가 (오버로딩) 메서드로 처리됩니다. 따라서 브리지 방법이 생성되지 않습니다.
참고 URL : https://stackoverflow.com/questions/5007357/java-generics-bridge-method
'ProgramingTip' 카테고리의 다른 글
Mercurial에서 기본 diff 도구를 사용합니까? (0) | 2020.11.28 |
---|---|
nonce를 만들고 사용하는 방법 (0) | 2020.11.28 |
실시간 공동 편집-어떻게 작동 작동? (0) | 2020.11.28 |
Java Primitives 범위 계산 (0) | 2020.11.28 |
applicationWillTerminate 언제 호출되고 호출되지 않을 때 (0) | 2020.11.28 |