6

我们有一个类似于这个的类层次结构:

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());
                                                     ^

另请注意,JDK 1.6 不会发生这种情况-target 1.5,仅使用 JDK 1.5

我在网上发现的唯一发生此错误的情况与执行以下操作有关:

double d = 2.0;
d.toString();

很明显问题出在哪里。

但在我的情况下它应该可以工作,因为很明显它getSubInterface()返回了一个SubInterface肯定具有该getField()方法的实现类。

那么这是一个编译器错误吗?mi.<SubInterface>getSubInterface()除了每次都做之外我还有什么选择(这有效,但由于 Eclipse 不会将此标记为错误,因此团队中的大多数人都忘记了这样做,而且他们中的大多数人只使用 JDK 1.6,所以他们没有注意到使用 maven/cmd 行编译时也可以)?

4

2 回答 2

1

我猜这是在 Java6 中修复的错误。

如下重写您的 main 方法将使 Java5 和 6 都可以工作:

public static void main(String[] args) {
    SubInterface subInterface = mi.getSubInterface();
    System.out.println(subInterface.getField());
}

似乎 Java5 需要赋值才能正确派生 type T,即使它已经声明为 extends SubInterface。Java6 正确地处理了这个并且不需要额外的分配。

于 2010-11-10T14:30:51.993 回答
1

检查错误:http ://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5003431

选项一:

SubInterface si = mi.getSubInterface();
si.getField();

选项二:

mi.<SubInterface>getSubInterface().getField()
于 2010-11-10T14:33:55.763 回答