Java 中 我们可以用类名.Calss or 对象名.getClass()去获得一个Class。
而这个Class本身也是一个类,而且是1个泛型类。
下面是Class源代码的中的定义:
* @author unascribed
* @see java.lang.ClassLoader#defineClass(byte[], int, int)
* @since JDK1.0
*/
public final class Class<T> implements java.io.Serializable,
GenericDeclaration,
Type,
AnnotatedElement {
private static final int ANNOTATION= 0x00002000;
private static final int ENUM = 0x00004000;
private static final int SYNTHETIC = 0x00001000;
private static native void registerNatives();
static {
registerNatives();
}
...
所以在反射中, 我们也可以使用泛型的。
这里只介绍两个常用的泛型类
Class<T>
Constructor<T>
一个例子
我们首先定义个苹果类
@ToString
class Apple{
private int id;
private double weight;
private Apple(int id, double weight){
this.id = id;
this.weight = weight;
}
}
可以见到这个类本身只有1个私有的全参数Constuctor, 所以这个类本身是无法在外部实例化的。
但是我们在其他类仍然可以利用反射构建1个对象
class TestReflect{
public Apple createObject(int id, double weight) throws NoSuchMethodException, SecurityException,
InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException{
Class clz = Apple.class;
Constructor cstr = clz.getDeclaredConstructor(int.class,double.class);
//because the constructor defined is private, we need below line to change it to be accessable,
//otherwise we will get the Exception below
//java.lang.IllegalAccessException: Class TestReflect can not access a member of class Apple with modifiers "private"
cstr.setAccessible(true);
Object obj = cstr.newInstance(id, weight);
Apple a = (Apple)obj;
return a;
}
}
这个例子我们没有使用泛型, 用Class 对象去获得 Apple.class 对象。
然后通过 Class 对象clz 去获得被定义的构造函数。 这个构造函数对象也是非泛型对象。
然后我们用setAccessible()方法修改这个私有构造函数可以被外部访问!
接下来newInstance()方法由于没有使用泛型, 所以只会返回1个Object 对象, 我们还需要强制转行成Apple对象。
使用泛型的反射例子
我们创建另1个构造苹果对象的方法:
public Apple createObjectWithGeneric(int id, double weight) throws NoSuchMethodException, SecurityException,
InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException{
Class<Apple> clz = Apple.class;
Constructor<Apple> cstr = clz.getDeclaredConstructor(int.class,double.class);
//because the constructor defined is private, we need below line to change it to be accessable,
//otherwise we will get the Exception below
//java.lang.IllegalAccessException: Class TestReflect can not access a member of class Apple with modifiers "private"
cstr.setAccessible(true);
Apple a = cstr.newInstance(id, weight);
return a;
}
一旦我们使用Class<Apple> 去接收 Apple.class 的对象
则Contructor<Apple> 这个泛型类就称为 getDeclaredConstructor()的返回类型了。
而其newInstance() 会直接return1个Apple 对象, 无需任何类型转换!