为什么实现这个通用接口会产生不明确的引用?

时间:2012-01-23 01:39:46

标签: java eclipse generics javac ambiguous

假设我有以下内容:

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<File>中实施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<File>accept方法实际应该是accept(File)并且没有歧义?另外,为什么这个错误只发生在javac上? (它适用于Eclipse的编译器。)

/编辑
除了创建第三个类之外,这个编译器问题的一个更简洁的解决方法是在public abstract boolean accept(File)中添加CombiningFileFilter方法。这消除了歧义。

/ E2
我使用的是JDK 1.7.0_02。

1 个答案:

答案 0 :(得分:1)

FileFilter接口中有一个方法与您的具体接口Filter<File>具有相同的签名。他们都有签名accept(File f)

这是一个含糊不清的引用,因为编译器无法知道在被覆盖的accept(File f, String name )方法调用中调用哪些方法。