Почему это переопределение общего метода работает с 1.6, но не 1.7?

Учитывая следующий класс, который переопределяет метод getListeners из AbstractListModel:

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, или я что-то не хватает?

Ответ 1

Прежде всего, AbstractListModel является общим, вы не должны наследовать его raw. Если

class GenericBug extends AbstractListModel<Something>

компилируется код.

Теперь он наследуется сырым, так что происходит? Необработанные типы экземпляров тоже подвергаются стиранию [4.8], поэтому raw AbstractListModel имеет метод

public EventListener[] getListeners(Class listenerType)

Метод GenericBug.getListeners в подклассе не отменяет этот метод [8.4.8.1].

Это основано на JLS3, который должен следовать Javac 6. Так что это, должно быть, ошибка Javac6.

Похоже, что javac 7 переписал алгоритмы системы типов с гораздо лучшим результатом.

JSL3: http://java.sun.com/docs/books/jls/third_edition/html/j3TOC.html