2012-08-24 1 views
3
public interface Foo <T> { 
    void setValue(T value); 
} 

public abstract class Bar extends JFormattedTextField{ 
    @Override 
    public void setValue(Object value) { 

    } 
} 

public class FooBar extends Bar implements Foo<String>{ 
    @Override //Foo 
    public void setValue(String aValue) { 
    // TODO Auto-generated method stub 

    } 

    @Override //Bar 
    public void setValue(Object aValue) { 
    // TODO Auto-generated method stub 

} 
} 

이 방법은 서로 동일 이름 일반적인 이름 충돌의 결과와 인터페이스와 추상 클래스를 구현

이름 충돌 결과 : Foo 타입의 메서드 SetValue (M)가 setValue에 같은 삭제를 가지고 (객체) 형식이 JFormattedTextField 인 경우 을 재정의하십시오.

왜 컴파일러에서 애정을 얻지 못하고 어떻게 해결할 수 있습니까?

+0

브릿지 메쏘드가 문제가됩니다 : http://stas-blogspot.blogspot.de/2010/03/java-bridge-methods-explained.html –

답변

3
:-) 1.4 일 위로 String`에 Foo의 유형을 변경하도록 조언합니다 간단히 말해서

: 컴파일러는 모든 메소드 호출 및 형식 변환이 작동하고,이 바이트 코드를 생성 할 Object를 사용하는지 확인 String를 사용합니다 :

이는 유형의 삭제 (Java generics - type erasure - when and what happens이 질문 참조)이다. 즉, 이제 동일한 서명을 가진 두 가지 방법이 있습니다 : public void setValue(Object aValue)

완벽한 해결책이 없습니다. 위의 코드를 Foo<String> 대신 Foo<Object>을 사용하여 컴파일 할 수 있지만 일반적으로 원하는 것은 아닙니다.

해결 방법은 어댑터를 사용하는 것입니다

public class FooBar extends Bar { 
    public Foo<String> adapt() { 
     return new Foo<String>() { 
      public void setValue(String value) { 
       FooBar.this.setValue(value); 
      } 
     } 
    } 
} 

기본적으로 수행해야 adapt() 방법은 올바른 인터페이스를 구현하고 this 모든 메소드 호출을 매핑하는 새 인스턴스를 만들 무엇인지.

+0

그래서 컴파일러가 내 FooBar- 클래스에서 setValue (Object value)로, Foo에서 구현 되었기 때문에? 그리고 Foo에서 구현하지 않았다면 setValue (String value)를 그대로 놔둘까요? 한 클래스에서 같은 이름을 가진 두 개의 메소드를 가질 수 있기 때문에 다른 매개 변수를 사용할 수 있습니까? – Torsten

+0

예. 그것은'T'가'String'이라는 것을 알고 있으며,'setValue (String)'이 인터페이스에 정의 된 메소드 여야한다는 것을 의미합니다. 바이트 코드를 생성 할 때 형식을 제대로 지울 수 있도록이 사실을 알아야합니다. –

+0

내 질문을 이해했는지 또는 귀하의 의견을 이해했는지 확실하지 않습니다. 어쨌든, 저는 해답을 해답으로 표시 할 것입니다, 왜냐하면 해답이 AmitD보다 더 빠르기 때문입니다. – Torsten

0

Java는 제네릭 용 유형 삭제를 사용합니다. 귀하의 경우 유형은 또한 개체의 하위 클래스입니다. 그리고 Bar 클래스는 Object를 허용하여 Nameclash가 발생합니다. 시나리오에서

당신이 확장 한 클래스에 매개 변수로 객체가 아닌 일반적인 기존의 클래스를 사용하고 있기 때문에 나는 메소드 이름을 변경하거나