反射机制
是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意属性和方法;
这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。
反射的应用
首先创建一个学生类
public class Student {
private String name;
private int age;
public Student() {
}
public Student(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
获取类名 三种方法
public class test {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
//Class.forName(全类名)方法
Class clazz = Class.forName("lalala.Student");
System.out.println(clazz);
//类名.class属性
Class clazz2 = Student.class;
System.out.println(clazz2);
//对象名.getClass()方法
Student s = new Student();
Class clazz3 = s.getClass();
System.out.println(clazz3);
}
}
获取构造方法
Constructor<?>[] getConstructors() | 返回所有公共构造方法对象的数组 |
Constructor<?>[] getDeclaredConstructors() | 返回所有构造方法对象的数组 |
Constructor<T> getConstructor(Class<?>... parameterTypes) | 返回单个公共构造方法对象 |
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) | 返回单个构造方法对象 |
创建对象的方法
如果是public的,直接创建对象 newInstance(Object... initargs)
如果是非public的,需要临时取消检查,然后再创建对象 setAccessible(boolean) 暴力反射
创建完要关闭权限
获取成员变量的方法
Field[] getFields() | 返回所有公共成员变量对象的数组 |
Field[] getDeclaredFields() | 返回所有成员变量对象的数组 |
Field getField(String name) | 返回单个公共成员变量对象 |
Field getDeclaredField(String name) | 返回单个成员变量对象 |
使用反射创建对象并赋值
public class test {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
//首先创建对象
Class clazz = Student.class;
//使用空参构造创建对象并赋值
//调用空参的构造方法,使用getConstructor()方法
Constructor constructor = clazz.getConstructor();
//创建对象,调用newInstance()方法,使用(Student)进行类型转换
Student student =(Student) constructor.newInstance();
//获取成员变量,对于私有的成员变量使用getDeclaredField()
Field field = clazz.getDeclaredField("name");
//修改私有的成员变量需要修改权限,使用setAccessible
field.setAccessible(true);
field.set(student,"a");
//关闭权限
field.setAccessible(false);
Field field1 = clazz.getDeclaredField("age");
field1.setAccessible(true);
field1.set(student,2);
field.setAccessible(false);
//打印结果,看是否赋值成功
System.out.println(student.getAge());
System.out.println(student.getName());
//使用有参构造创建对象并赋值
//调用有参构造方法,在括号里写上参数类型
Constructor constructor1 = clazz.getDeclaredConstructor(int.class,String.class);
//直接使用newInstance赋值
Student student1 =(Student) constructor1.newInstance(3,"张三");
System.out.println(student1);
}
}
set和get方法给成员变量赋值
//首先创建一个类,类中直接为name属性赋值为helloKitty
public class PrivateTest {
private String name = "helloKitty";
public PrivateTest() {
this.name = name;
}
public String getName() {
return name;
}
}
//主函数操作
import java.lang.reflect.Field;
public class test {
public static void main(String[] args) throws NoSuchFieldException, InstantiationException, IllegalAccessException {
//获取Class对象
Class clazz = PrivateTest.class;
//获得属性name
Field field = clazz.getDeclaredField("name");
//修改私有属性权限
field.setAccessible(true);
//创建对象
PrivateTest privateTest = new PrivateTest();
//用set修改对象属性,将姓名改为Kitty
field.set(privateTest,"kitty");
//用get获取修改后的值
System.out.println(field.get(privateTest));
}
}