> 文档中心 > JAVA高级--反射机制

JAVA高级--反射机制


JAVA高级–反射机制


文章目录

  • JAVA高级--反射机制
  • 一、反射是什么?反射有什么用?
    • 1.一般流程与反射流程的对比
    • 2.反射机制提供主要功能
  • 二、反射的关键类--Class类
    • 1.获取Class的几种方式
    • 2.其他类型获取Class
    • 3.何种情况出现相同的Class
  • 三、获取运行时对象信息
    • 小结
  • 四、创建运行时对象
  • 五、调用运行时类的指定方法
    • 注:
  • 六、调用运行时类的指定属性
    • 注:

一、反射是什么?反射有什么用?

  1. 反射机制可以让程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。
  2. 加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构。

1.一般流程与反射流程的对比

在这里插入图片描述

2.反射机制提供主要功能

1.在运行时判断任意一个对象所属的类
2.在运行时构造任意一个类的对象
3.在运行时判断任意一个类所具有的成员变量和方法
4.在运行时获取泛型信息
5.在运行时调用任意一个对象的成员变量和方法
6.在运行时处理注解
7.生成动态代理

二、反射的关键类–Class类

上文所说,反射机制是一种可以在运行时获取类信息的机制,而这个Class类我们将它理解成是每一个类对应的信息(Class本身也是一个类),每个类有且只有一个,里面包含了构造器,字段,方法等类的基本信息,我们可以用getClass()方法获取对应信息,然后进行操作。

1.获取Class的几种方式

// 1.知道具体的类,通过具体类的class属性获取对应的Class Class hashMapClass = HashMap.class;  // 2.根据类的实例getClass获取对应的Class Boolean aBoolean = new Boolean(true); Class booleanClass = aBoolean.getClass();  // 3.根据全类名的信息,通过forName查找,(可能抛出异常) try {     Class<?> aClass = Class.forName("java.util.concurrent.locks.ReentrantLock"); } catch (ClassNotFoundException e) {     e.printStackTrace(); }

2.其他类型获取Class

Class listClass = List.class;// 接口的Class Class intClass = Integer.class;// 类的Class int arr[] = new int[10]; Class arrClass = arr.getClass();// 数组Class Class enumClass = Month.class;// 枚举Class Class baseTypeClass = boolean.class;// 基础数据类型Class Class annoClass = Target.class;// 注解Class

3.何种情况出现相同的Class

只要是相同的类或者相同维度的Class,两者是同一个Class,如同样是一维数组,两者是同一个Class

System.out.println(new int[10].getClass() == new int[1000].getClass());//true

三、获取运行时对象信息

  // 获取运行时类的信息    public static void getClassInfo()    { Student student = new Student(); Class<? extends Student> studentClass = student.getClass(); // 实现接口的信息 Class<?>[] interfaces = studentClass.getInterfaces(); for (Class<?> anInterface : interfaces) {     System.out.println(anInterface.getName()); } // 父类的信息 Class<?> superclass = studentClass.getSuperclass(); System.out.println(superclass.getName()); // 所有public构造器 Constructor<?>[] constructors = studentClass.getConstructors(); // 所有构造器 Constructor<?>[] declaredConstructors = studentClass.getDeclaredConstructors(); for (Constructor<?> constructor : declaredConstructors) {     //构造器修饰符     System.out.println(constructor.getModifiers());     //构造器名称 名字为全类名     System.out.println(constructor.getName());     //构造器参数     for (Class<?> parameterType : constructor.getParameterTypes()) {  System.out.println(parameterType);     } } Method[] methods = studentClass.getMethods(); Method[] declaredMethods = studentClass.getDeclaredMethods(); for (Method declaredMethod : declaredMethods) {     //方法权限     System.out.println(declaredMethod.getModifiers());     //方法名     System.out.println(declaredMethod.getName());     //方法参数     for (Class<?> parameterType : declaredMethod.getParameterTypes()) {  System.out.println(parameterType);     }     //返回参数     System.out.println(declaredMethod.getReturnType());     //方法抛出的异常     for (Class<?> exceptionType : declaredMethod.getExceptionTypes()) {  System.out.println(exceptionType);     } } //获取public的属性信息 Field[] fields = studentClass.getFields(); //获取所有的属性信息 Field[] declaredFields = studentClass.getDeclaredFields(); for (Field declaredField : declaredFields) {     //属性权限     System.out.println(declaredField.getModifiers());     //属性类型     System.out.println(declaredField.getType());     //属性名称     System.out.println(declaredField.getName()); }    }
public class Student extends People implements Comparable, Cloneable{    private String name;    private String stuNo;    private Integer age;    public Student(String name)    { this.name = name;    }    private Student(String name, Integer age)    { this.name = name; this.age = age;    }    Student()    {    }    protected Student(String name, String stuNo, Integer age)    { this.name = name; this.stuNo = stuNo; this.age = age;    }    public String getName()    { return name;    }    public void setName(String name)    { this.name = name;    }    public String getStuNo()    { return stuNo;    }    public void setStuNo(String stuNo)    { this.stuNo = stuNo;    }    public Integer getAge()    { return age;    }    public void setAge(Integer age)    { this.age = age;    }    @Override    public String toString()    { return "Student{" + "name='" + name + '\'' + ", stuNo='" + stuNo + '\'' + ", age=" + age + '}';    }    @Override    public int compareTo(Object o)    { return 0;    }     private Integer selfIntroduction(String city)    { System.out.println(name + "来自:" + city); return age;    }}
public class People{    private Double money;    public Double getMoney()    { return money;    }    public void setMoney(Double money)    { this.money = money;    }}

小结

1.获取属性,构造器,方法权限信息为getModifiers;
2.获取参数列表为getParameterTypes;
3.获取全部权限信息为getDeclared【Fields,Methods,Constructors】()。

四、创建运行时对象

// 3.Class获取对应的构造器    public static void getConstructorByClass()     throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException    { // 1.获取Class Class<Student> studentClass = Student.class; // 2.调用指定参数结构的构造器,生成Constructor的实例 Constructor<Student> constructor1 = studentClass.getConstructor();// 空参构造器实例 //创建实例 Student student1 = constructor1.newInstance(); System.out.println("student1 = " + student1); Constructor<Student> constructor2 = studentClass.getConstructor(String.class);// 参数为string的构造器实例 Student student2 = constructor2.newInstance("小明"); System.out.println("student2 = " + student2);    }

五、调用运行时类的指定方法

// 5.调用运行时类的指定方法    public static void useMethodByClass()     throws NoSuchMethodException, InvocationTargetException, IllegalAccessException    { Student student = new Student("夏洛"); System.out.println(student); Class<? extends Student> studentClass = student.getClass(); Method method1 = studentClass.getMethod("setAge", Integer.class); // 返回值 Object invoke1 = method1.invoke(student, 10); System.out.println(invoke1); System.out.println(student); // 没有参数的方法 Method method2 = studentClass.getMethod("getName"); // 返回值 Object invoke2 = method2.invoke(student); System.out.println(invoke2); // 私有方法 Method method3 = studentClass.getDeclaredMethod("selfIntroduction", String.class); // setAccessible(true) 将方法设置为显示调用 method3.setAccessible(true); // 返回值 Object invoke3 = method3.invoke(student, "厦门"); System.out.println(invoke3);    }

注:

1.Object 对应原方法的返回值,若原方法无返回值,此时返回null
2.若原方法若为静态方法,此时形参Object obj可为null
3.若原方法形参列表为空,则Object[] args为null(或者不填)

六、调用运行时类的指定属性

// 6.调用运行时类的指定属性    public static void useFieldByClass() throws NoSuchFieldException, IllegalAccessException { Student student = new Student("小白"); System.out.println(student); Class<? extends Student> studentClass = student.getClass(); // 获取字段实例 Field nameField = studentClass.getDeclaredField("name"); nameField.setAccessible(true); //设置值 nameField.set(student,"花花"); System.out.println(student);    }

注:

1.Method和Field、Constructor对象都有setAccessible()方法;
2.setAccessible启动和禁用访问安全检查的开关。