反射
反射是指:在运行期间可以知道一个对象的所有信息
1 反射常用API
1.1 获取反射中的Class对象
(1)通过类的 全路径字符串
获取Class,例如:
Class clz = Class.forName("java.lang.String");
(2)使用 类.class
方法,例如:
String.class
(3)通过 对象.getClass()
方法,例如:
String string = "hello world";
Class clz = string.getClass();
1.2 Class常用API
(1) Field[] getFields()
返回这个类或其超类的公共字段的Field对象数组。如果Class对象描述的是基本类型或者数组类型,将返回一个长度为0的数组。
(2) Field[] getDeclaredFields()
返回这个类的全部字段对应的Field对象数组。如果Class对象描述的是基本类型或者数组类型,将返回一个长度为0的数组。
(3)Field getField(String name)
返回指定名称的Field。如果不存在对应名称的字段,则抛出异常 NoSuchFieldException
。
(4)Field getDeclaredField(String name)
返回指定名称的Field。如果不存在对应名称的字段,则抛出异常 NoSuchFieldException
。
(5) Method[] getMethods()
返回所有的公共方法,包括从超类继承来的公共方法。
(6) Method[] getDeclaredMethods()
返回这个类或者接口的所有方法,但是不包括从超类继承的方法。
(7) Constructor[] getConstructors()
返回这个类的公共构造方法。
(8) Constructor[] getDeclaredConstructors()
返回这个类的全部构造方法。
(9) String getPackageName
得到包含这个类型的包的包名。如果该类是一个数组类型,则返回元素类型所属的包。如果是基本数据类型,则返回 “java.lang”。
1.3 程序实践
测试类:
@Data
public class Employee {
private int id;
private String name;
private int age;
public Employee(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public Employee() {
}
}
测试代码:
@Test
public void test3() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {
// 获得类
Class aClass = Class.forName("com.lqk.entity.Employee");
Employee employee = (Employee) aClass.newInstance();
System.out.println(employee.toString());
// 获得属性,设置为可访问,设置value
Field name = aClass.getDeclaredField("name");
name.setAccessible(true);
name.set(employee, "Tom");
Field age = aClass.getDeclaredField("age");
age.setAccessible(true);
age.set(employee, 100);
System.out.println(employee.toString());
// 获取方法, 执行方法
Method toString = aClass.getMethod("toString");
String employeeString = (String) toString.invoke(employee);
System.out.println(employeeString);
}
程序输出:
Employee(id=0, name=null, age=0)
Employee(id=0, name=Tom, age=100)
Employee(id=0, name=Tom, age=100)