对泛型T、Class<T>、Class<?>的理解:
首先Class类 ,普通的非泛型类Class。注意:class是java的关键字, 在声明java类时使用。
Class类的实例表示Java应用运行时的类(class ans enum)或接口(interface and annotation)(每个java类运行时都在JVM里表现为一个Class对象,可通过类名.class,类型.getClass(),Class.forName("类名")等方法获取Class对象)。
数组同样也被映射为为Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本类型boolean,byte,char,short,int,long,float,double和关键字void同样表现为 Class 对象。
/**
* 此方法是一个非泛型类中的泛型方法,参数为Class<T>类型,可以传入任何类,但是Class<T>将参数在函数内部的类型固定为 T类,使用clazz.newInstance(),返回的类型也为固定的 T 类型。
* 如: 传入Dog.class, 函数中的 T 固定为Dog.class,函数返回的是Dog类型,不需要强制转换为Dog类型
*/
public static <T> T creatNew1(Class<T> clazz) throws IllegalAccessException, InstantiationException {
T entity = clazz.newInstance();
return entity;
}
/**
* Class<? extends T>,受限统配,表示T的一个未知子类。
* 此方法参数是Class<? extends Animal>,只能传入Animal子类的类型,函数返回类型只能声明为Animal或Object类型,
* 如:传入Cat.class,函数返回一个Animal的子类对象,需将此子类对象强制转换为具体的子类(即Cat类)。
*/
public static Animal creatNew2(Class<? extends Animal> clazz) throws IllegalAccessException, InstantiationException {
Animal animal = clazz.newInstance();
return animal;
}
/**
* 此方法参数是Class,可传入任何类,其返回只能声明为Object类对象。
* 如:传入Dog.class, 返回的是Object类型的对象,需强制转换为Dog类型的对象。
*/
public static Object creatNew3(Class clazz) throws IllegalAccessException, InstantiationException {
System.out.println(clazz);//打印具体传入的类型。
return clazz.newInstance();
}
/**
* Class<T> 在实例化的时候,T 要替换成具体类。其返回只能声明为 T 对象。
* Class<?> 它是个通配泛型,? 可以代表任何类型。其返回只能声明为 Object 类对象。
* 传入参数Class<?> 和 上一个方法传入 Class clazz的区别:Class<?> 中的 ? 是通配符,其实就是表示任意符合泛类定义条件的类,
* 和直接使用 Class 效果基本一致,但是这样写更加规范,在某些类型转换时可以避免不必要的 unchecked 错误。
* 如:Cat.class, 返回的是Object类型的对象,需强制转换为Cat类型的对象。
*/
public static Object creatNew4(Class<?> clazz) throws IllegalAccessException, InstantiationException {
System.out.println(clazz);//打印具体传入的类型。
return clazz.newInstance();
}
/**
* 传入Object类型的对象,返回也声明为Object类型。
*/
public static Object creatNew5(Object object) {
System.out.println(object.getClass());//打印具体传入的类型。
return object;
}
参考: