JAVA 泛型 - Class<T>
public class BeanUtilsHashMapper<T> implements HashMapper<T, String, String> {
private Class<T> type;
public BeanUtilsHashMapper(Class<T> type) {
this.type = type;
}
public T fromHash(Map<String, String> hash) {
T instance = org.springframework.beans.BeanUtils.instantiate(type);
try {
BeanUtils.populate(instance, hash);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
return instance;
}
private HashMapper<QuestShows, String, String> createHashMapper() {
return new DecoratingStringHashMapper<QuestShows>(new BeanUtilsHashMapper<QuestShows>(QuestShows.class));
}
一、 随着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 类型(boolean
、byte
、char
、short
、int
、long
、float
和 double
)和关键字 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); |
Class<T>在实例化的时候,T要替换成具体类
Class<?>它是个通配泛型,?可以代表任何类型