Java反射机制
基本概念
Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。
应用场景
- JDBC连接数据库class.forName("");
- mybatis生成代码工具;
- springIOC容器 < bean id=“” class=“类的完整路径”>
- 自定义注解(AOP+反射)
- 其它第三方框架;
- 破解常用的单例(枚举例外)
获取class信息的三种方式
Student类
Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Demo {
public static void main(String[] args) throws ClassNotFoundException {
// 获取class的三种方式
// 第一种
Class student = Student.class;
System.out.println(student.getSimpleName());
// 第二种
Class students = Class.forName("com.ls.javase.reflection.Student");
System.out.println(students.getSimpleName());
// 第三种
Class newStudent = new Student().getClass();
System.out.println(student.getSimpleName());
}
}
利用反射机制实例化对象
public class Demo {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
// 获取class的三种方式
// 第一种
Class studentClass = Student.class;
System.out.println(studentClass.getSimpleName());
// 第二种
// Class students = Class.forName("com.ls.javase.reflection.Student");
// System.out.println(students.getSimpleName());
// 第三种
// Class newStudent = new Student().getClass();
// System.out.println(newStudent.getSimpleName());
// 利用反射机制实例化对象
Student student = (Student) studentClass.newInstance();
student.setName("五月天");
System.out.println(student.getName());
// 使用反射,调用类的无参构造方法 实例化对象
Constructor constructor = studentClass.getConstructor();
Student newStudent = (Student) constructor.newInstance();
newStudent.setName("阿信");
System.out.println(newStudent.getName());
// 使用反射,调用类的有参构造方法 实例化对象
Constructor constructors = studentClass.getConstructor(String.class, Integer.class);
Student newStudents = (Student) constructors.newInstance("怪兽", 18);
System.out.println(newStudents);
}
}
运行结果
Student
执行了无参构造方法!
五月天
执行了无参构造方法!
阿信
Student{name=‘怪兽’, age=18}
使用反射机制实例化对象
Student student = (Student) studentClass.newInstance();
使用反射机制调用无参构造函数实例化对象
// 使用反射,调用类的无参构造方法 实例化对象
Constructor constructor = studentClass.getConstructor();
Student newStudent = (Student) constructor.newInstance();
使用反射机制调用有参构造函数实例化对象
Constructor constructors = studentClass.getConstructor(String.class, Integer.class);
Student newStudents = (Student) constructors.newInstance("怪兽", 18);
使用反射机制给属性赋值
public class Demo {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
// 第一种
Class studentClass = Student.class;
System.out.println(studentClass.getSimpleName());
// 利用反射机制实例化对象
Student student = (Student) studentClass.newInstance();
student.setName("五月天");
System.out.println(student.getName());
Field name = studentClass.getDeclaredField("name");
name.setAccessible(true);
name.set(student,"石头");
System.out.println(student.getName());
}
}
因为Student类的name属性是私有属性,所以需要使用name.setAccessible(true);给权限才能操作该属性,否则会抛权限不足异常!
使用反射机制调用方法
在Student类中新增sing方法
public void sing(String name) {
System.out.println(name + "唱了一首知足!");
}
使用反射机制调用方法
public class Demo {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
// 获取class
Class studentClass = Student.class;
System.out.println(studentClass.getSimpleName());
// 利用反射机制实例化对象
Student student = (Student) studentClass.newInstance();
student.setName("五月天");
System.out.println(student.getName());
// 使用反射机制调用方法
Method sing = studentClass.getDeclaredMethod("sing",String.class);
sing.invoke(student,"阿信");
}
}
运行结果
阿信唱了一首知足!
如文章有误,欢迎批评指正,欢迎交流。