Discuss / Java / 关于 static <K> K[] pickTwo(K k1, K k2, K k3), static <T> T[] asArray(T... objs) 两个方法的个人理解

关于 static <K> K[] pickTwo(K k1, K k2, K k3), static <T> T[] asArray(T... objs) 两个方法的个人理解

Topic source

CXM

#1 Created at ... [Delete] [Delete and Lock User]

asArray方法的参数长度是可变的,实际上也就是一个泛型数组,但我们无法直接创建泛型数组,需要借助反射的方式,同理,在此处,因为asArray方法需要一个泛型数组,那jvm就根据泛型实例的类型使用反射的方式自动帮我们创建了一个指定类型的数组,然后返回该数组;

pickTwo方法分为两部分,首先我们需要传入三个泛型参数,当编译的时候直接被擦除类型,实际上就是传入了三个Object类型的参数,然后再将第一第二个参数传递给asArray方法,那么此时asArray方法接收的就是Object类型的参数,jvm就创建了Object数组,然后返回该数组;

做一个我得出这个结论的说明:   那就是两次调用asArray方法传递的参数类型是不同的!!!

直接使用asArray()时:

asArray("one", "two", "three"),jvm会根据参数类型帮我们创建String[];

asArray(1, 2, 3),jvm会根据参数类型创建Integer[];

在pickTwo()中使用asArray()时:

pickTwo("one", "two", "three"),编译的时候进行泛型类型的擦除,传递给asArray的参数类型则是Object类型的,所以jvm根据参数类型创建了Object[];

贴一段代码佐证:(声明的变量类型以及变量名是我使用idea自动生成局部变量的方式生成的)

String str = "haha";Object obj = str;Class<?> aClass = obj.getClass();//Class<?> 等价于 Class<? extends Object>Class<? extends String> aClass1 = str.getClass();Class<? extends String> aClass2 = "haha".getClass();Class<? extends Integer> aClass3 = Integer.valueOf(1).getClass();

CXM

#2 Created at ... [Delete] [Delete and Lock User]

最后的代码格式乱掉了,重新传一下

String str = "haha";
Object obj = str;

Class<?> aClass = obj.getClass();

Class<? extends String> aClass1 = str.getClass();
Class<? extends String> aClass2 = "haha".getClass();
Class<? extends Integer> aClass3 = Integer.valueOf(1).getClass();

CXM

#3 Created at ... [Delete] [Delete and Lock User]

其实就是因为方法中参数可变(T... ojbs),这种情况比较特殊,jvm必须生成一个泛型数组,不过泛型擦除是肯定存在的操作,那jvm如何生成一个指定类型的数组呢?那就是看变量的声明,如果变量再进行泛型擦除前的声明不是Object的,那就按照擦除前声明的类型创建数组;如果变量在进行泛型擦除前的声明是Object类型的,那就不用管之前是什么类型的,直接生成Object数组。

Poss

#4 Created at ... [Delete] [Delete and Lock User]

纯纯误认子弟。。。。


  • 1

Reply