Joh*_*oth 10 java arrays wildcard bounds type-parameter
在Java中,为什么数组不能是类型变量的绑定,但可以是通配符的绑定?
你可以有:
List< ? extends Integer[] > l;
Run Code Online (Sandbox Code Playgroud)
但你不能拥有:
class MyClass< T extends Integer[] > { } // ERROR!
Run Code Online (Sandbox Code Playgroud)
为什么?
考虑这个Java代码:
package test;
public class Genric<E>
{
public Genric(E c){
System.out.println(c.getClass().getName());
}
public static void main(String[] args) {
new Genric<Integer[]>(new Integer[]{1,2});
}
}
Run Code Online (Sandbox Code Playgroud)
对于你的第一个案例:
List< ? extends Integer[] > l;
Run Code Online (Sandbox Code Playgroud)
当您执行类似这样List< ? extends Integer[] > l;的操作时,Java编译器会将其视为a List< ? extends Object> l;并相应地进行转换.所以这就是为什么你没有得到任何错误.
生成的字节码如下:
.
.
.
20: aastore
21: invokespecial #52; //Method "<init>":(Ljava/lang/Object;)V
24: return
.
.
Run Code Online (Sandbox Code Playgroud)
查看第21行.虽然,我已经通过了一系列的java.lang.Integer; 在内部它被翻译成java.lang.Object.
对于你的第二个案例:
class MyClass< T extends Integer[] > { } // ERROR!
Run Code Online (Sandbox Code Playgroud)
根据java语言规范:
TypeParameter:
TypeVariable TypeBoundopt
TypeBound:
extends ClassOrInterfaceType AdditionalBoundListopt
.
.
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,绑定仅由类或接口组成(甚至不是原始类型).所以,当你做这样的事情class MyClass< T extends Integer[] > { }再Integer[]没有资格作为一个类或接口.
根据我对Java Spec的理解,这样做是为了解决所有场景
class MyClass< T extends Integer[] >class MyClass< T extends Integer[][] >class MyClass< T extends Integer[][]...[] > 因为所有这些都可以表示为java.lang.Object和作为参数传递时,如示例所示
public Genric(E c){
System.out.println(c.getClass().getName());
}
Run Code Online (Sandbox Code Playgroud)
因为'c'记得它的真实类型.
希望这会有所帮助.