内部类类型参数由封闭类类型变量绑定

时间:2011-01-27 23:42:42

标签: java generics

有没有办法将封闭类声明的类型变量用作内部类中声明的类型变量的绑定?

class Test<E> {
   class Inner<T extends E> {}
   <T extends E> void doStuff(T arg) {}
   public static void main(String[] args) {
      new Test<Number>().doStuff(new Integer(0)); // works fine, as expected
      new Test<Number>().new Inner<Integer>(); // won't compile
   }
}

javac给出了这个错误:

Test.java:6: type parameter java.lang.Integer is not within its bound
             new Test<Number>().new Inner<Integer>();
                                             ^

我找不到满足编译器的任何类型组合。 TInner声明的类型参数doStuff之间的区别是什么?为什么一个工作而另一个不工作?

我不是在寻找替代方案,我只是想更好地理解语言的运作方式。

1 个答案:

答案 0 :(得分:3)

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6557954

Bug ID: 6557954
Votes   2
Synopsis    Inner class type parameters doesn't get substituted when checking type well-formedness
Category    java:compiler
Release Fixed    7(b40)
State   10-Fix Delivered, bug
Priority:   5-Very Low
Submit Date 16-MAY-2007
Posted Date : 2008-07-02 16:22:46.0

说明

  

编译器无法接受此程序:

class Foo<T> {
  class Bar<U extends T> {}
  Foo<Number>.Bar<Integer> f;
}

评估

  

这是Check.java中的一个问题,因为在检查绑定一致性时,实际类型参数仅在最顶层的类型变量的绑定中被替换。在这种情况下,我们要根据实际的类型参数检查Foo.Bar T = Number,U = Integer

     

所以应该是这样的情况:

Number <: Object
Integer <: [Number/T]T = Number
  

不幸的是,javac错过了第二次替换,以便检查成为:

Integer <: T 
  

哪个错误并导致错误。

修改

在我的系统上,问题中的代码与Java 7 javac编译时没有错误:

C:\workspace\Sandbox\src>"%JAVA_HOME%\bin\javac.exe" -version
javac 1.7.0-ea

但它因Java 6 javac的问题中指出的错误而失败:

C:\workspace\Sandbox\src>"%JAVA_HOME%\bin\javac.exe" -version
javac 1.6.0_17