传递给方法的无界通配符
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
是特定的虽然未知类型。
编译器可以自由地推断出与参数类型和返回类型兼容的任何内容。 在你的情况下,它总是可以推断T
为Object
。 这将签名转变为
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 ...