我们有一个类似于这个的类层次结构:
public class TestDereference {
private static MainInterface mi = new MainInterfaceImpl();
public static void main(String[] args) {
System.out.println(mi.getSubInterface().getField());
}
}
interface MainInterface {
<T extends SubInterface> T getSubInterface();
}
interface SubInterface {
Field getField();
}
class Field {
@Override
public String toString() {
return "Hooray!";
}
}
class SubInterfaceImpl implements SubInterface {
Field f = new Field();
public Field getField() {
return f;
}
}
class MainInterfaceImpl implements MainInterface {
SubInterfaceImpl si = new SubInterfaceImpl();
public <T extends SubInterface> T getSubInterface() {
return (T) si;
}
}
接口实际上有多个实现,但这不是问题。使用Eclipse编译器或Java 1.6进行编译就可以正常工作(如ideone所示)。但是,如果我尝试使用Java 1.5(这是我们项目的要求之一)编译它,则会出现以下错误:
TestDereference.java:12: test.SubInterface cannot be dereferenced
System.out.println(mi.getSubInterface().getField());
^
另请注意,使用-target 1.5
的JDK 1.6也不会发生这种情况,只能使用JDK 1.5
我在网络上发现此错误的唯一情况与执行以下操作有关:
double d = 2.0;
d.toString();
显而易见的问题是什么。
但我的情况应该有效,因为很明显getSubInterface()
会返回SubInterface
实现类,但肯定有getField()
方法。
这是编译器错误吗?除了每次mi.<SubInterface>getSubInterface()
之外我还有什么选择(这有效,但是由于Eclipse没有将此标记为错误,团队中的大多数人都忘了这样做,而且大多数人只使用JDK 1.6他们在用maven / cmd行编译时没注意到它?)
答案 0 :(得分:1)
我想这是一个在Java6中修复的错误。
按如下方式重写主要方法将使Java5和6中的工作正常:
public static void main(String[] args) {
SubInterface subInterface = mi.getSubInterface();
System.out.println(subInterface.getField());
}
似乎Java5需要赋值才能正确派生类型T
,即使它已经声明为扩展SubInterface
。 Java6正确处理这个问题,不需要额外的任务。
答案 1 :(得分:1)
检查错误:http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5003431
选项一:
SubInterface si = mi.getSubInterface();
si.getField();
选项二:
mi.<SubInterface>getSubInterface().getField()