一、反射的概述
Java的反射机制是在运行状态时,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象都能够调用它的任意一个方法和属性。这种动态获取的信息以及动态调用的方法的功能称为Java语言的反射机制。==反射就是把类中的各种成分封装成一个对象,根据这些个对象来创建类的实例。==
二、反射的使用
2.1 获取类对象
获取Class对象有两种,一种是类.class,一种是Class.forName()。.class适用于在编译时已经知道具体的类。
- .class
Class cl = String.class;
System.out.println(cl);
输出:
class java.lang.String
- Class.forName()
try {
Class<?> aClass = Class.forName("java.lang.String");
System.out.println(aClass.getName());
} catch (ClassNotFoundException e) {
System.out.println("找不到String类");
}
输出:
java.lang.String
2.2 获取类的成员
Student测试类:
public class Student {
private String name;
private Integer age;
public Student(String name, Integer age) {
this.name = name;
this.age = age;
System.out.println("name: " + name + " age: " + age);
}
public Student(String name) {
this.name = name;
System.out.println("name: " + name);
}
public Student() {
}
private Student(Integer age) {
this.age = age;
System.out.println("age: " + age);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
2.2.1 获取类的构造函数
获取所有的构造方法:
public static void main(String[] args) throws ClassNotFoundException {
Class<?> aClass = Class.forName("com.example.demo.thread.Student");
Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors();
for (Constructor constructor : declaredConstructors) {
//获取构造方法的权限修饰符
System.out.print("权限修饰符:" + Modifier.toString(constructor.getModifiers()) + " 参数类型:");
//获取构造方法的参数类型
Class[] parameterTypes = constructor.getParameterTypes();
for (int i = 0; i < parameterTypes.length; i++) {
System.out.print(parameterTypes[i].getSimpleName() + " ");
}
System.out.println(" ");
}
}
输出:
权限修饰符:private 参数类型:Integer
权限修饰符:public 参数类型:
权限修饰符:public 参数类型:String
权限修饰符:public 参数类型:String Integer
获取特定的构造方法:
获取无参构造方法:
try {
Constructor<?> constructor = aClass.getConstructor();
System.out.println(constructor);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
输出:
public com.example.demo.thread.Student()
获取有参构造方法:
Class[] p = {String.class, Integer.class};
try {
Constructor<?> constructor = aClass.getConstructor(p);
System.out.print(Modifier.toString(constructor.getModifiers()) + "参数:");
Class[] parametertypes = constructor.getParameterTypes();
for (int j = 0; j < parametertypes.length; j++) {
System.out.print(parametertypes[j].getSimpleName() + " ");
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
输出:
public参数:String Integer
调用构造函数:
Class[] p = {String.class, Integer.class};
try {
Constructor<?> constructor = aClass.getConstructor(p);
Object instance = constructor.newInstance("张三", 22);
System.out.println(instance);
} catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
输出:
name: 张三 age: 22
com.example.demo.thread.Student@4d7e1886
调用私有构造方法:
Class[] p1 = {Integer.class};
try {
Constructor<?> constructor = aClass.getDeclaredConstructor(p1);
constructor.setAccessible(true);
Student instance = (Student) constructor.newInstance(20);
System.out.println(instance.getAge());
} catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
输出:
20
2.2.2 获取类的方法
try {
Method method = aClass.getDeclaredMethod("setAge", Integer.class);
Object arg1s[] = {10};
Student student1 = Student.class.newInstance();
method.invoke(student1, arg1s);
System.out.println(student1.getAge());
} catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
输出:
10
2.2.3 获取类的成员变量
try {
Field field = aClass.getDeclaredField("age");
Student student = new Student("zs", 21);
try {
field.setAccessible(true);
field.set(student, 20);
System.out.println(student.getAge());
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
输出:
20