获得类的构造器
通过反射获得类的Class对象,然后就要获得其构造器,才能去创建对象。
package testReflect;
import java.lang.reflect.Constructor;
//自定的一个类
class MyClass {
private int a1;// 私有成员1
private double a2;// 私有成员2
// 默认权限的构造器
MyClass(int b) {
this.a1 = b;
}
// public权限的无参构造器
public MyClass() {
}
// public权限的有参构造器
public MyClass(double b) {
this.a2 = b;
}
// private权限的有参构造器
private MyClass(int b1, double b2) {
this.a1 = b1;
this.a2 = b2;
}
}
// 在主类main方法中测试
public class Main {
public static void main(String[] args) {
try {
// 加载类
Class cls = Class.forName("testReflect.MyClass");
// 获取所有public权限的构造器
Constructor[] ary_con1 = cls.getConstructors();
System.out.println("所有public权限的构造器:");
for (Constructor c : ary_con1) {
System.out.println(c);
}
// 获取所有的构造器
Constructor[] ary_con2 = cls.getDeclaredConstructors();
System.out.println("所有的构造器:");
for (Constructor c : ary_con2) {
System.out.println(c);
}
// 获取指定的public构造器,传入的是参数表所在的类的Class对象表
Constructor con3 = cls.getConstructor(double.class);
System.out.println("指定的public构造器:");
System.out.println(con3);
// 获取指定的构造器,传入的是参数表所在的类的Class对象表
Constructor con4 = cls.getDeclaredConstructor(int.class,
double.class);
System.out.println("指定的构造器:");
System.out.println(con4);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
}
}
输出:
所有public权限的构造器:
public testReflect.MyClass(double)
public testReflect.MyClass()
所有的构造器:
private testReflect.MyClass(int,double)
public testReflect.MyClass(double)
public testReflect.MyClass()
testReflect.MyClass(int)
指定的public构造器:
public testReflect.MyClass(double)
指定的构造器:
private testReflect.MyClass(int,double)
创建类的对象并使用成员
在使用构造器和使用成员时都可以通过.setAccessible(true)
解除限定来越过权限检查。
package testReflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
//自定的一个类
class MyClass {
private int a1;// 私有成员1
private double a2;// 私有成员2
// private权限的有参构造器
private MyClass(int b1, double b2) {
this.a1 = b1;
this.a2 = b2;
System.out.println("private构造器被调用了");
}
// private权限的成员方法
private String setNum(int b1, double b2) {
this.a1 = b1;
this.a2 = b2;
System.out.println("private成员方法被调用了");
return "返回值";
}
}
// 在主类main方法中测试
public class Main {
public static void main(String[] args) {
try {
// 加载类
Class cls = Class.forName("testReflect.MyClass");
// 获取指定的构造器,传入的是参数表所在的类的Class对象表
Constructor con = cls.getDeclaredConstructor(int.class,
double.class);
// 暴力反射,让这个私有构造器对象可以越过权限检查
con.setAccessible(true);
// 使用这个构造器创建对象,传入参数
Object obj = con.newInstance(2, 3.14);
// 从Class对象获取指定的成员方法
Method mthd = cls.getDeclaredMethod("setNum", int.class,
double.class);
// 暴力反射,让这个私有成员方法对象可以越过权限检查
mthd.setAccessible(true);
// 调用该成员方法,于刚才创建的对象上,还需传入参数
Object rslt = mthd.invoke(obj, 9, 6.66);
System.out.println("返回值是:" + rslt.toString());
// 从Class对象获取指定的成员
Field f1 = cls.getDeclaredField("a1");
Field f2 = cls.getDeclaredField("a2");
// 暴力反射,让这两个私有成员变量可以越过权限检查
f1.setAccessible(true);
f2.setAccessible(true);
// 为第二个成员变量设置值,于刚才创建的对象上,还需传入值
f2.set(obj, 8.88);
// 输出这两个字段的值,于刚才创建的对象上
System.out.println("a1=" + f1.get(obj) + ",a2=" + f2.get(obj));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}
输出:
private构造器被调用了
private成员方法被调用了
返回值是:返回值
a1=9,a2=8.88