Допустим, у меня есть следующее:
public interface Filter<E> {
public boolean accept(E obj);
}
и
import java.io.File;
import java.io.FilenameFilter;
public abstract class CombiningFileFilter extends javax.swing.filechooser.FileFilter
implements java.io.FileFilter, FilenameFilter {
@Override
public boolean accept(File dir, String name) {
return accept(new File(dir, name));
}
}
В его нынешнем виде вы можете использовать javac для компиляции CombiningFileFilter
. Но если вы также решите реализовать Filter
в CombiningFileFilter
, вы получите следующую ошибку:
CombiningFileFilter.java:9: error: reference to accept is ambiguous,
both method accept(File) in FileFilter and method accept(E) in Filter match
return accept(new File(dir, name));
^
where E is a type-variable:
E extends Object declared in interface Filter
1 error
Однако, если я создам третий класс:
import java.io.File;
public abstract class AnotherFileFilter extends CombiningFileFilter implements
Filter<File> {
}
Существует больше не ошибка компиляции.Ошибка компиляции также исчезает, если Filter
не является универсальным:
public interface Filter {
public boolean accept(File obj);
}
Почему компилятор не может определить, что, поскольку класс реализует Filter
, accept
метод должен быть accept (File)
и что нет двусмысленности? Кроме того, почему эта ошибка возникает только с javac? (Он отлично работает с компилятором Eclipse.)
/ edit
Более чистый способ решения этой проблемы компилятора, чем создание третьего класса, - это добавить метод public abstract boolean accept (File)
в CombiningFileFilter
. Это стирает двусмысленность.
/ e2
Я использую JDK 1.7.0_02.