给定以下类,它从AbstractListModel中覆盖getListeners方法:
import java.util.EventListener; import javax.swing.AbstractListModel; public class GenericBug extends AbstractListModel { /** * This is the method of interest * This is the exact same method signature that is present in the base class */ @Override public <T extends EventListener> T[] getListeners(Class<T> listenerType) { // do something useful here... return super.getListeners(listenerType); } // Not important here @Override public int getSize() { return 0; } @Override public Object getElementAt(int index) { return null; } }
该类使用Oracle 1.6 JDK编译好的.尝试使用Oracle 1.7 JDK完全相同的类,我收到编译错误说有一个名称冲突,但该方法不被覆盖(但它是!!)
这是我使用JDK7时遇到的错误:
% /usr/java/jdk1.7.0/bin/javac GenericBug.java GenericBug.java:10: error: name clash: <T#1>getListeners(Class<T#1>) in GenericBug and <T#2>getListeners(Class<T#2>) in AbstractListModel have the same erasure,yet neither overrides the other public <T extends EventListener> T[] getListeners(Class<T> listenerType) { ^ where T#1,T#2 are type-variables: T#1 extends EventListener declared in method <T#1>getListeners(Class<T#1>) T#2 extends EventListener declared in method <T#2>getListeners(Class<T#2>) GenericBug.java:12: error: incompatible types return super.getListeners(listenerType); ^ required: T[] found: EventListener[] where T is a type-variable: T extends EventListener declared in method <T>getListeners(Class<T>) GenericBug.java:9: error: method does not override or implement a method from a supertype @Override ^ Note: GenericBug.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. 3 errors
有人可以向我解释发生了什么吗?这是JDK1.7中的编译器错误,还是我错过了什么?
解决方法
首先,AbstractListModel是通用的,你不应该继承它原始的.如果
class GenericBug extends AbstractListModel<Something>
代码编译.
现在它是继承原始的,所以发生了什么?原始类型的实例方法全部都被擦除[4.8],所以原始的AbstractListModel有一个方法
public EventListener[] getListeners(Class listenerType)
子类中的GenericBug.getListeners方法不会覆盖此方法[8.4.8.1].
这是基于JLS3,Javac 6应该遵循.所以它一定是一个Javac6的bug.
似乎javac 7已经重写了类型系统算法,结果更好.
JSL3:http://java.sun.com/docs/books/jls/third_edition/html/j3TOC.html