目录
引言
反射概念
反射获取类对象
反射获取构造器对象
获取构造器对象并使用
反射获取成员变量对象
反射获取方法对象
反射获取成员方法并使用
引言
经过前面的学习,相信大家已经能够对网络编程有了一定的了解,而我们的Java基础知识也要在本次的学习之后结束了,希望之前总结的Java知识能够对你有所帮助。本次我们学习的内容是Java中的反射,这也是一个非常重要的知识点,在这个时候大家可千万不能够放弃学习啊。而且在学习过Javase之后,才会发现这只是冰山一角,废话不多说了,我们开始今天的学习吧!
反射概念
反射是指对于任何一个Class类,在"运行的时候"都可以直接得到这个类全部成分
- 在运行时,可以直接得到这个类的构造器对象:constructor
- 在运行时,可以直接得到这个类的成员变量对象:Field
- 在运行时,可以直接得到这个类的成员方法对象:Method
这种运行时动态获取类信息以及动态调用类中成分的能力称为Java语言的反射机制。
反射的关键HelloWorld.java -> javac -> HelloWorld.java
Class c = HelloWorld.java
反射获取类对象
首先,反射的第一步是需要获取类的对象,只有获取了类的对象,才可以进一步获取其他的对象,在此共有三种方法可以获取类的对象:
1、在源代码阶段,通过Class类中的静态方法forName(全限名:包名+类名) 获取;
//Student为要获取的类对象 Class c1 = forNmae("Student");
2、在class对象阶段,通过类名.class直接获取
Class c2 = Student.class
3、在Runtime运行时阶段通过对象获取
Student student = new Student(); Class c3 = student.getClass();
反射获取构造器对象
在前面获取Class类对象之后,便可以获取其类中构造器对象。
Class类中常用于获取构造器的方法
方法 说明 Constructor<?>[]getconstructors() 返回所有构造器对象的数组(只能拿public的) constructor<?>[] getDeclaredconstructors() 返回所有构造器对象的数组,存在就能拿到 Constructor<T> getconstructor(class<?>... parameterTypes) 返回单个构造器对象(只能拿public的) Constructor<T> getDeclaredConstructor(class<?>... parameterTypes) 返回单个构造器对象,存在就能拿到
/** 1、返回所有构造器对象的数组(只能拿public的) getconstructors() */ Class c1 = Student.class; Constructor[] constructors = c1.getconstructors(); /** 2、返回所有构造器对象的数组,存在就能拿到 getDeclaredconstructors() */ Class c2 = Student.class; Constructor[] constructors = c2.getDeclaredconstructors(); /** 3、返回单个构造器对象(只能拿public的) getconstructor(根据参数个数获取构造器,若无参,则获取无参构造器) */ Class c3 = Student.class; Constructor constructor = c3.getconstructor(); /** 4、返回单个构造器对象,存在就能拿到 getDeclaredconstructor(规则同上) */ Class c4 = Student.class; Constructor constructor = c4.getDeclaredconstructor(String.class,int.class);
获取构造器对象并使用
获取构造器的作用是初始化一个对象返回
方法 说明 T newInstance(Object ...inittargs) 根据指定的构造器创建对象 public void setAccessible(boolean flag) 设置为true,表示取消访问检查,进行暴力反射 //1、获取单个构造器 Class c = Student.class; Constructor constructor = c4.getDeclaredconstructor(); //2、调用方法创建对象 Student s = (Student)constructor.newInstance();
在运行代码过后发现并不能创建对象,会直接报错,这是什么原因呢?这是因为获取的构造器是私有的,不能用来直接创建,因此需要用到另一个方法进行暴力反射。在第三行加一行代码
constructor.setAccessible(true);
反射获取成员变量对象
反射的第一步是先得到类对象,然后从类对象中获取类的成分对象
Class类中用于获取成员变量的方法
方法 说明 Field[ ]getFields() 返回所有成员变量对象的数组〈只能拿public的) Field[ ]getDeclaredFields() 返回所有成员变量对象的数组,存在就能拿到 Field getField(String name) 返回单个成员变量对象(只能拿public的) Field getDeclaredField(String name) 返回单个成员变量对象,存在就能拿到
/** 1、返回所有成员变量对象的数组〈只能拿public的) getFields() */ Class c = Student.class; Field[] fields = c.getFields(); /** 2、返回单个成员变量对象(只能拿public的) getDeclaredField() */ Class c = Student.class; Field field = c.getDeclaredField("name");
Field的方法:给成员变量赋值和取值
方法 说明 void set(Object obj,Object value) 给对象定义某个成员变量数据 Object get(Object obj) 获取对象成员变量的值 public void setAccessible(boolean flag) 设置为true,表示取消访问检查,进行暴力反射 Class getType() 获取属性的类型,返回class对象 String getName() 获取属性的名称 //1、获取Student对象类 Class c = Student.class; //2、通过对象类获取name成员变量 Field name = c.getDeclaredField("name"); //3、定义Student类,并为其成员变量name赋值 Student s = new Student(); name.set(s,"石原里美");//s.setName("石原里美")
在运行的过程之中,我们同样会遇到和之前一样的错误,不能对私有成员变量赋值,因此还需要对其进行暴力反射,需要在第二步之后添加一行代码name.setAccessible(true);
反射获取方法对象
反射的第一步先得到类对象,然后从类对象中获取类的方法对象
Class类中用于获取成员方法的方法
方法 说明 Method[ ] getNethods() 返回所有成员方法对象的数组(只能拿public的) Method[ ] getDeclaredMethods() 返回所有成员方法对象的数组,存在就能拿到 Method getMethod(String name,class<?>... parameterTypes) 返回单个成员方法对象(只能拿public的) Method getDeclaredMethod(String name,Class<?>... parameterTypes) 返回单个成员方法对象,存在就能拿到 //1、获取类对象中所有方法 Class c = Student.class; Method[] methods = c.getDeclaredMethods(); //2、根据参数获取单个方法 Class c = Student.class; Method m1 = c.getDeclaredMethod("study");//无参数方法 Method m2 = c.getDeclaredMethod("study",String.class);//若存在方法重载,则需要根据参数区分
反射获取成员方法并使用
Method类中用于触发执行的方法
方法 说明 object invoke(object obj, object. . . args)
运行方法:
参数一:用obj对象调用该方法
参数二:调用方法的传递的参数(如果没有就不写)返回值:方法的返回值(如果没有就不写)
Class c = new Student(); Method method = c.getDeclaredMethod("study"); Object result = method.invoke(c);
注意:若没有返回值,则直接返回null,另外若是私有方法则需要对其进行暴力反射。若有参数,则在对象之后传输。
创作不易,给个三连