2013-10-06 3 views
0

브리지 메서드 만들기에 대한 몇 가지 질문이 있습니다. 공변량 무시를 위해 브리지 기법을 적용 할 수 있습니다. 이제 공식 도움말을 예로 들어 보겠습니다.브리지 메서드 만들기

public class Node<T>{ 
    private T data; 
    public Node(T data){ this.data=data;} 
    public void setData(T data){ 
     System.out.println("Node.setData"); 
     this.data=data; 
    } 
} 
public class MyNode extends Node<Integer>{ 
    public MyNode(Integer data){ super(data); } 
    public void setData(Integer data){ 
     System.out.println("MyNode.setData"); 
     this.data=data; 
    } 
} 

브릿지 방법이 만들어지지 않도록합시다. 따라서 런타임 클래스 MyNode에는 setData(Integer)setData(Object)의 두 가지 방법이 있습니다. 여기서 마지막은 Node에서 상속됩니다. 우리가 전화 할 때 setData(new Inetegr(5))setData(Integer)이라고합니다. 우리가 Object o= new Integer(5); setData(o);이라고 쓰면 setData(Object)이라고합니다. 그것은 사실이 아닙니다. 두 가지 질문 :

  1. 소개 브리지 방법의 이유를 올바르게 알고 있습니까?
  2. 브리지 방법을 만드는 데 필요한 충분 조건은 무엇입니까?
+0

안녕하세요 - 아마도 여기에 대한 답변을 읽어 보면 큰 도움이됩니다. http://stackoverflow.com/questions/5007357/java-generics-bridge-method – Meesh

답변

2

소개 브리지 방법이 올바르게 도입 된 이유는 무엇입니까?

나는 그렇다고 생각합니다. 컴파일러가 브릿지 메소드를 생성하지 않았다면, 서브 클래스의 메소드는 오버라이드 된 버전이 아닌 수퍼 클래스 메소드의 오버로드 된 버전이 될 것입니다. 당신이 이미 이해하는 것처럼.

브리지 방법을 만드는 데 필요한 충분 조건은 무엇입니까?

매개 변수화 된 형식을 확장하거나 구현할 때 erasure 형식을 사용하면 수퍼 클래스에서 메서드의 서명이 변경됩니다. 우리는 다음 Object o= new Integer(5); setData(o);을 작성하는 경우

setData(Object)가 호출됩니다. 그것은 사실이 아닙니다.

나는 그것이 무엇을 의미하는지 이해하지 못합니다. 비 제너릭 코드에서이 동작을 테스트해야합니다. 메서드가 오버로드되면 메서드 호출은 전달 된 매개 변수의 선언 된 형식에 따라 컴파일 타임에 결정되는 메서드에 바인딩됩니다. 이 경우에 선언 된 유형은 Object이므로 setData(Object) 버전을 호출합니다.

+0

_ 이해가 안됩니다. 그게 무슨 뜻이야? 원시 타입 선언을하자. Node m = new MyNode (5); 객체 o = 새로운 정수 (5); m.setData (o);'. 가상 메서드의 특정 구현을 선택하면 런타임에 개체 유형별로 결정됩니다. 하지만'setData (Object)'메소드는'MyNode'에서 오버라이드되지 않습니다. 그러므로'Node'의 메소드가 호출 될 것입니다. –

+0

_ 파라미터 화 된 타입을 확장하거나 구현할 때 erasure 타입을 사용하면 수퍼 클래스에서 메소드의 시그니처가 변경됩니다. _ 그러나 공변 재 지정의 경우 매개 변수화 된 타입이 없을 수도 있습니다. 그러나 교량 방법은 창조하고있다. 브리지 방식을 만드는 또 다른 조건은 없습니다. –

1

우리가 아니라 다리 기법을 적용하는 컴파일러입니다. 귀하의 경우 컴파일러에서 그것은 사항 setData (개체)가 여기에 다리

class MyNode extends Node<Integer> { 
    public void setData(Object data) { 
    setData((Integer) data); 
    } 
... 

를 삽입하고이 사항 setData (정수)이없는

Node<Integer> n = new MyNode(); 
    n.setData(1); 

노드

을 사용하는 이유입니다 것입니다. MyNode 브리지 메소드 setData (Object)가이를 오버라이드합니다. JVM은 실제 n 유형이 MyNode임을 감지하고 setData (Integer)로 리디렉션 할 MyNode.setData (Object)를 호출합니다.

다리 방법이 적용되는 또 다른 경우는

class X implements Cloneable { 
    @Override 
    pubic X clone() { 
     ... 
    } 

다리가 실제로 따라서 Object.clone를 오버라이드 (override) 할 필요가 공변 반환 형식을합니다.참고 바이트 코드 메서드 서명에 반환 유형이 포함되어 있습니다.