一、什么是反射

Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。
本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息。
通过反射,可以在运行时动态地创建对象并调用其属性。

二、反射的原理及优缺点

三、反射的应用与基本功能

1、反编译:.class -> .java
2、通用框架。如:Spring中通过XML文件配置Bean。
基本功能

在运行时判断任意一个对象所属的类; 在运行时判断任意一个类的对象 在运行时判断任意一个类所具有的成员变量及方法 在运行时调用任意一个对象的方法

重点:在运行时而不是编译时。

四、反射机制常用的类

  1. java.lang.Class
  2. java.lang.reflect.Constructor
  3. java.lang.reflect.Field
  4. java.lang.reflect.Method
  5. java.lang.reflect.Modifier

五、反射的基本使用方法

  1. package com.cimon.reflectdemo;
  2. public class Student {
  3. @Getter
  4. private int age;
  5. Student (int age){
  6. this.age = age;
  7. }
  8. Student(){
  9. this.age = 12;
  10. }
  11. private Student(String age){
  12. this.age = Integer.valueOf(age);
  13. }
  14. public int doHomework(){
  15. return 1;
  16. }
  17. public String toString(){
  18. return String.valueOf(this.age);
  19. }
  20. }

5.1、获取Class

1、Object -> getClass 2、任何数据类型(包括基本的数据类型)都有一个“静态”的class属性。 3、通过class类的静态方法:forName(String className)。常用。

运行期间,一个类只有一个Class对象产生。

  1. public class StudentTest {
  2. public static void main(String args[]) throws ClassNotFoundException{
  3. //方式一
  4. Student student = new Student(12);
  5. Class studentClass1 = student.getClass();
  6. System.out.println(studentClass1.getName());
  7. //方式二
  8. Class studentClass2 = Student.class;
  9. System.out.println(studentClass2.getName());
  10. //方式三
  11. Class studentClass3 = Class.forName("com.cimon.reflectdemo.Student");
  12. System.out.println(studentClass3.getName());
  13. System.out.println(studentClass2==studentClass1);
  14. System.out.println(studentClass3==studentClass1);
  15. }
  16. }
  17. 运行结果:
  18. com.cimon.reflectdemo.Student
  19. com.cimon.reflectdemo.Student
  20. com.cimon.reflectdemo.Student
  21. true
  22. true

5.2、类的实例判断

  1. public native boolean isInstance(Object obj);

5.3、创建实例:反射

方法一:使用Class对象的newInstance()方法

  1. Class<?> c = String.Class;
  2. Object str = c.newInstance();

方法二:通过Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance方法来创建对象。这种方法可以指定参数

  1. Class<?> c = String.class;
  2. Constructor constructor=c.getConstructor(String.class);
  3. Object obj = constructor.newInstance(“hello reflection”);

5.4、使用反射获取构造方法

  1. 1、批量获取方法
  2. public Constructor[] getConstructors(); //所有公有方法
  3. public Constructor[] getDeclaredConstructors(); // 获取所有构造方法(私有、保护...)
  4. 2、单个获取的方法
  5. public Constructor getConstructors(Class.. parameterTypes) 获取单个的公有构造方法
  6. public Constructor getDeclaredConstructors(Class.. parameterTypes) 获取单个的构造方法
  7. 3、调用构造方法
  8. Contructor.newInstance(Obejct... initargs) //指定初始化参数
  1. package com.cimon.reflectdemo;
  2. import java.lang.reflect.Constructor;
  3. import java.lang.reflect.InvocationTargetException;
  4. public class ContructorTest {
  5. public static void main(String args[]) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
  6. Class studentClass = Class.forName("com.cimon.reflectdemo.Student");
  7. Constructor[] constructors = studentClass.getDeclaredConstructors();
  8. for(Constructor c : constructors){
  9. System.out.println(c);
  10. }
  11. System.out.println(" ...... 调用构造方法..... ");
  12. Constructor c1 = studentClass.getDeclaredConstructor(String.class);
  13. System.out.println(c1);
  14. c1.setAccessible(true);// 强制访问
  15. Object obj = c1.newInstance("123");
  16. }
  17. }
  18. 运行结果:
  19. private com.cimon.reflectdemo.Student(java.lang.String)
  20. com.cimon.reflectdemo.Student()
  21. com.cimon.reflectdemo.Student(int)
  22. ...... 调用构造方法.....
  23. private com.cimon.reflectdemo.Student(java.lang.String)

5.5 获取成员变量

  1. package com.cimon.reflectdemo;
  2. import java.lang.reflect.Field;
  3. import java.lang.reflect.InvocationTargetException;
  4. public class FiledTest {
  5. public static void main(String args[]) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
  6. Class studentClass = Class.forName("com.cimon.reflectdemo.Student");
  7. Field[] fields = studentClass.getDeclaredFields();
  8. for(Field f : fields){
  9. System.out.println(f);
  10. }
  11. System.out.println("...... 测试设置属性 .......");
  12. Object student = studentClass.getDeclaredConstructor(java.lang.Integer.TYPE).newInstance(12);
  13. System.out.println("before set ... " + student);
  14. Field f = studentClass.getDeclaredField("age");
  15. f.setAccessible(true);
  16. f.set(student,123);
  17. System.out.println("after set ... " + student);
  18. }
  19. }
  20. 运行结果:
  21. private int com.cimon.reflectdemo.Student.age
  22. ...... 测试设置属性 .......
  23. before set ... 12
  24. after set ... 123

5.6 获取方法

使用invoke调用获取到的方法。

  1. public Object invoke(Object obj, Object... args)
  2. throws IllegalAccessException, IllegalArgumentException,InvocationTargetException
  1. package com.cimon.reflectdemo;
  2. import java.lang.reflect.InvocationTargetException;
  3. import java.lang.reflect.Method;
  4. public class MethodTest {
  5. public static void main(String args[]) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
  6. Class studentClass = Class.forName("com.cimon.reflectdemo.Student");
  7. Method[] methods = studentClass.getDeclaredMethods();
  8. for(Method m : methods){
  9. System.out.println(m);
  10. }
  11. System.out.println(" ..... 测试方法 ....");
  12. Object obj = studentClass.getDeclaredConstructor(int.class).newInstance(123);
  13. Method m1 = studentClass.getDeclaredMethod("getAge");
  14. Object result = m1.invoke(obj);
  15. System.out.println(result);
  16. }
  17. }
  18. 运行结果:
  19. public java.lang.String com.cimon.reflectdemo.Student.toString()
  20. public int com.cimon.reflectdemo.Student.doHomework()
  21. public int com.cimon.reflectdemo.Student.getAge()
  22. ..... 测试方法 ....
  23. 123

F、参考

深入解析Java反射(1) - 基础
Java基础篇:反射机制详解