2010-11-10 37 views
6

取消引用错误我们有类似这样的类层次结构:太阳JDK 1.5无法与泛型

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要么发生,只能用其中很明显的问题是什么

double d = 2.0; 
d.toString(); 

:JDK 1.5

唯一的情况下,当出现这个错误,我在网上找到相关的这样搞。

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

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

+0

您正在使用哪种确切的JDK版本? (5和6?) – 2010-11-10 12:58:07

+0

1.5.0_22和1​​.6.0_20(根据'javac -version') – 2010-11-10 13:21:11

+0

当您尝试使用编译器标志'-source 1.5'或者将Eclipse编译器符合性级别设置为1.5而不是1.6? – 2010-11-10 14:05:12

回答

1

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

选项之一:

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

选项二:

mi.<SubInterface>getSubInterface().getField() 
+0

所以我猜如果我被困在1.5中,除了这两个选项之外我没有太多的工作可做。我希望有更优雅的想法,但这是必须要做的。 – 2010-11-10 21:31:35

+0

我接受了你的答案,也提供了错误报告的链接,这表明它只在1.6 – 2010-11-11 08:46:17

1

我想这是一个在Java6中修复的bug。

重写你的主要方法如下会使事情都Java5的6工作:

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

看来Java5中需要正确推导型T,即使它已经宣布延长SubInterface分配。 Java6可以正确处理这一点,并且不需要额外的分配。