打字猴:1.700447621e+09
1700447621 明白了这个问题,我们就把泛型数组声明为泛型类的子类型吧!代码如下:
1700447622
1700447623 public static<T>T[]toArray(List<T>list, Class<T>tClass){
1700447624
1700447625 //声明并初始化一个T类型的数组
1700447626
1700447627 T[]t=(T[])Array.newInstance(tClass, list.size());
1700447628
1700447629 for(int i=0,n=list.size();i<n;i++){
1700447630
1700447631 t[i]=list.get(i);
1700447632
1700447633 }
1700447634
1700447635 return t;
1700447636
1700447637 }
1700447638
1700447639 通过反射类Array声明了一个T类型的数组,由于我们无法在运行期获得泛型类型的参数,因此就需要调用者主动传入T参数类型。此时,客户端再调用就不会出现任何异常了。
1700447640
1700447641 在这里我们看到,当一个泛型类(特别是泛型集合)转变为泛型数组时,泛型数组的真实类型不能是泛型类型的父类型(比如顶层类Object),只能是泛型类型的子类型(当然包括自身类型),否则就会出现类型转换异常。
1700447642
1700447643
1700447644
1700447645
1700447646 编写高质量代码:改善Java程序的151个建议 [:1700438174]
1700447647 编写高质量代码:改善Java程序的151个建议 建议101:注意Class类的特殊性
1700447648
1700447649 Java语言是先把Java源文件编译成后缀为class的字节码文件,然后再通过ClassLoader机制把这些类文件加载到内存中,最后生成实例执行的,这是Java处理的基本机制,但是加载到内存中的数据是如何描述一个类的呢?比如在Dog.class文件中定义的是一个Dog类,那它在内存中是如何展现的呢?
1700447650
1700447651 Java使用一个元类(MetaClass)来描述加载到内存中的类数据,这就是Class类,它是一个描述类的类对象,比如Dog.class文件加载到内存中后就会一个Class的实例对象描述之。因为Class类是“类中类”,也就有预示着它有很多特殊的地方:
1700447652
1700447653 无构造函数。Java中的类一般都有构造函数,用于创建实例对象,但是Class类却没有构造函数,不能实例化,Class对象是在加载类时由Java虚拟机通过调用类加载器中的defineClass方法自动构造的。
1700447654
1700447655 可以描述基本类型。虽然8个基本类型在JVM中并不是一个对象,它们一般存在于栈内存中,但是Class类仍然可以描述它们,例如可以使用int.class表示int类型的类对象。
1700447656
1700447657 其对象都是单例模式。一个Class的实例对象描述一个类,并且只描述一个类,反过来也成立,一个类只有一个Class实例对象,如下代码返回的结果都为true:
1700447658
1700447659 //类的属性class所引用的对象与实例对象的getClass返回值相同
1700447660
1700447661 String.class.equals(new String().getClass())
1700447662
1700447663 “ABC”.getClass().equals(String.class)
1700447664
1700447665 //class实例对象不区分泛型
1700447666
1700447667 ArrayList.class.equals(new ArrayList<String>().getClass()))
1700447668
1700447669 Class类是Java的反射入口,只有在获得了一个类的描述对象后才能动态地加载、调用,一般获得一个Class对象有三种途径:
1700447670
[ 上一页 ]  [ :1.700447621e+09 ]  [ 下一页 ]