传递给方法的无界通配符

public class ColTest { static T wildSub(ArrayList holder, T arg){ T t=holder.get(0); return t; } public static void main(String[] args) { ArrayList list=new ArrayList(Arrays.asList(2L,3L,7L)); Long lng=1L; ColTest.wildSub(list, lng); } } 

真的很感兴趣为什么这个片段是合法的,因为wildSub的签名只接受T ArrayList或从T派生,以及类型为T arg。 但表示 – 某些特定类型,未知,以及它如何满足编译器? 毕竟类型并不意味着

这是由于捕获转换 。 在内部,编译器将表达式Foo的类型转换为Foo ,其中X是特定的虽然未知类型。

编译器可以自由地推断出与参数类型和返回类型兼容的任何内容。 在你的情况下,它总是可以推断TObject 。 这将签名转变为

 static Object wildSub(ArrayList holder, Object arg) 

这意味着它可以将任何ArrayList作为第一个参数,任何东西作为第二个参数。 由于您没有对返回值执行任何操作,因此Object将没问题。

如果你把它当作编译器使用Object在哪里? 使用它,它编译的原因是有道理的。 这就是它的全部。

如果你做任何依赖的操作? 作为某个类,如果传入了错误的类,您将在运行时获得强制转换exception。

作为对现有(正确)答案的补充,使其更加清晰:

  ... Object result1 = ColTest.wildSub(list, lng); //compiles fine with Sun's javac // Long result2 = ColTest.wildSub(list, lng); //does not compile without explicit casting Long result2 = (Long) ColTest.wildSub(list, lng); //compiles fine ...