反射,在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
public class Flection {
public static void main(String[] args) throws Exception {
Class<Book> clazz = Book.class;
Constructor<Book> constructor = clazz.getDeclaredConstructor();
// true的值表示反射对象应该在使用时抑制Java语言访问检查
constructor.setAccessible(true);
System.out.println("反射实例化私有构造器");
Book book = constructor.newInstance();
System.out.println(book);
System.out.println("反射执行私有方法");
// 反射获取方法
Method method = clazz.getDeclaredMethod("read");
// 取消对方法的访问控制
method.setAccessible(true);
// 调用私有方法
method.invoke(book);
// 查询所有public属性
Field[] fields = clazz.getFields();
// 查询所有访问控制类型的属性,但包括集成的属性
Field[] fields1 = clazz.getDeclaredFields();
System.out.println(fields.length + "\n" + fields1.length);
// 反射获取属性值
System.out.println("public Field:" + fields[0].getName() + " = " + fields[0].getInt(book));
// 反射改变属性值
fields[0].setInt(book, 12345);
System.out.println(book.i);
}
}
class Book {
private String name = "java";
public int i = 0;
protected int a = 1;
int b = 2;
private Book() {
System.out.println("私有构造器");
}
private void read() {
System.out.println("read book");
}
@Override
public String toString() {
return "Book{" + "name='" + name + '\'' + ", i=" + i + ", a=" + a + ", b=" + b + '}';
}
}
通过反射批量执行类的方法
public void beansTest() throws Exception {
String list = "com.eg.egsc.scp.accesscontrolcomponent.dto.CardInfoDto,"
+ "com.eg.egsc.scp.accesscontrolcomponent.dto.CardInfoListDto,"
+ "com.eg.egsc.scp.accesscontrolcomponent.dto.OpenRecordDto,"
+ "com.eg.egsc.scp.accesscontrolcomponent.dto.UserDto,"
+ "com.eg.egsc.scp.accesscontrolcomponent.bo.AlarmEventBO,"
+ "com.eg.egsc.scp.accesscontrolcomponent.bo.AlarmEventInfo,"
+ "com.eg.egsc.scp.accesscontrolcomponent.bo.BaseBO,"
+ "com.eg.egsc.scp.accesscontrolcomponent.bo.DeviceBO,"
+ "com.eg.egsc.scp.accesscontrolcomponent.bo.GroupBO,"
+ "com.eg.egsc.scp.accesscontrolcomponent.entity.AlarmEvent,"
+ "com.eg.egsc.scp.accesscontrolcomponent.entity.AlarmRecord,"
+ "com.eg.egsc.scp.accesscontrolcomponent.entity.AuthCredence,"
+ "com.eg.egsc.scp.accesscontrolcomponent.entity.DeviceAuth,"
+ "com.eg.egsc.scp.accesscontrolcomponent.entity.DeviceAuthGroupRelation,"
+ "com.eg.egsc.scp.accesscontrolcomponent.entity.DeviceGroup,"
+ "com.eg.egsc.scp.accesscontrolcomponent.entity.DeviceGroupMapping,"
+ "com.eg.egsc.scp.accesscontrolcomponent.entity.InformationRecord,"
+ "com.eg.egsc.scp.accesscontrolcomponent.entity.OpenRecord";
String[] split = list.split(",");
for (int i = 0, size = split.length; i < size; i++) {
Class c = Class.forName(split[i]);
invokeMethod(c);
}
}
/**
* 调用方法
*
* @param c 类class
* @throws Exception void
*/
public static void invokeMethod(Class c) throws Exception {
// 获得类的所有方法
Method[] methods = c.getDeclaredMethods();
// 加载类实例
Object obt = Class.forName(c.getName()).newInstance();
for (Method method : methods) {
// 获取所有参数类型
Class<?>[] classes = method.getParameterTypes();
Object arg = null;
if (classes.length > 0) {
// 有参数
for (Class<?> classzz : classes) {
String name = classzz.getName();
if (name.equals("int")) {
arg = 1;
} else if (name.equals("java.util.List")) {
arg = new ArrayList<>();
} else if (name.equals("java.util.Date")) {
arg = new Date();
} else if (name.equals("short")) {
arg = (short) 1;
} else if (name.equals("[Ljava.lang.Integer;")) {
arg = new Integer[1];
} else if (name.equals("java.lang.Integer")) {
arg = 1;
} else if (name.equals("float")) {
arg = 10.1f;
} else if (name.equals("java.lang.String")) {
arg = "";
} else if (name.equals("java.lang.Object")) {
arg = new Object();
} else if (name.equals("java.lang.Short")) {
arg = (short) 1;
} else {
arg = null;
}
System.out.println(classzz.getName());
MethodUtils.invokeMethod(obt, method.getName(), arg);
}
} else if (!"$jacocoInit".equals(method.getName())) {
// 无参
MethodUtils.invokeMethod(obt, method.getName(), null);
}
}
}
}