欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JAVA 泛型 - Class

程序员文章站 2024-03-15 13:10:17
...

一、 随着Java的发展,类Class已经泛型化了。但是随之而来会有一系列的疑问,Class<T> 中类型参数 T 的含义是什么?Class<T>和Object有什么区别?

 

实际上,在之前的JDK版本中,Class.newInstance() 方法的定义返回 Object,您很可能要将该返回类型强制转换为另一种类型:

class Class {
     Object newInstance();
 }

 

但是使用泛型,您定义 Class.newInstance() 方法具有一个更加特定的返回类型:

 

class Class<T> {
     T newInstance();

 

二、类型参数:

T指的是由此 Class 对象建模的类的类型。例如,String.class 的类型是 Class<String>。如果将被建模的类未知,则使用 Class<?>

三、java中Class<T>的完整定义为:

public final class Class<T> extends Object implements Serializable,
                       GenericDeclaration, Type, AnnotatedElement

 

Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本的 Java 类型(booleanbytecharshortintlongfloatdouble)和关键字 void 也表示为 Class 对象。Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。

以下示例使用 Class 对象来显示对象的类名:

 

void printClassName(Object obj) {
         System.out.println("The class of " + obj +
                            " is " + obj.getClass().getName());
     }
 

 

还可以使用一个类字面值来获取指定类型(或 void)的 Class 对象。例如:

 

 System.out.println("The name of class Foo is: "+ Foo.class.getName());
 

 

 

四、如何创建一个Class<T>类型的实例?

      就像使用非泛型代码一样,有两种方式:调用方法 Class.forName() 或者使用类常量X.class。      Class.forName() 被定义为返 回 Class<?>。另一方面,类常量 X.class 被定义为具有类型 Class<X>,所 以 String.class 是Class<String> 类型的。

       让 Foo.class 是 Class<Foo> 类型有什么好处?

       大的好处是,通过类型推理的魔力,可以提高使用反射的代码的类型安全。另外,还不需要将 Foo.class.newInstance() 强制类型转换为 Foo。比如有一个方法,它从数据库检索一组对象,并返回 JavaBeans 对象的一个集合。您通过反射来实例化和初始化创建的对象,但是这并不意味着类型安全必须完全被抛至脑后。例如下面这个方法:

public static<T> List<T> getRecords(Class<T> c, Selector s) {
     // Use Selector to select rows
     List<T> list = new ArrayList<T>();
     for (/* iterate over results */) {
         T row = c.newInstance(); // use reflection to set fields from result
         list.add(row);
      }
      return list;
}

 

可以简单的像下面这样简单地调用该方法:

 

List<FooRecord> l = getRecords(FooRecord.class, fooSelector);