Reflect
- 在java中“万事万物皆是对象”,也就是万事万物都是各种各样的类,而对于类而言又可以进一步的抽象成为一类,来描述各种类,其一个实例对象就是一种类。反射(reflect)就是把一个类的各个成员映射成相对应的类型,我们通过方法可以得到一种类的字节码文件,在通过字节码文件来实现对这一种类进行操作比如实例化、修改属性,调用方法等。
- 获取字节码的三种方式:可以通过类,或者是一个类的一个具体实例对象,也可以通过那个类(描述类的那个类)方式如下:
Class c = Class.forName("com.zrm.Student");//通过类类
Class c1 = Student.class;//通过类名
Class c2 =
student.getClass();//类的实例对象
package com.zrm;
import java.lang.reflect.Constructor;
import java.rmi.StubNotFoundException;
public class ReFlect1 {
public static void main(String[] args) throws Exception {
Student student = new Student();
//获取反射的三种方式
Class c = Class.forName("com.zrm.Student");//通过类类
Class c1 = Student.class;//通过类名
Class c2 = student.getClass();//类的实例对象
//在获取到字节码后可以通过方法得到这个类里面成员所对应的类型
/*
对于一个类的描述分为四个部分:
package对应的Package
属性对应的Field
构造方法对应的Construct
method对应的Method
*/
//得到Student类的构造方法
Constructor constructor = c.getConstructor();//无参构造方法
//通过构造方法来实例化一个对象
Student student1 = (Student) constructor.newInstance();
System.out.println(student);
//--------------------------有参构造
Constructor constructor1 = c1.getConstructor(String.class, int.class, int.class);
Student student2 = (Student) constructor1.newInstance("fjx", 18, 100);
System.out.println(student2);
}
}
反射创建对象的效率比传统方式差很多
//---------------------------通过反射获取对象属性------------
/*
* 通过反射获取非私有属性(public protected default)
* 通过暴力反射获取私有属性(private)
*
* */
//先获取Student类对象
Class studentClass = Class.forName("com.zrm.Student");
//获取构造器对象
Constructor constructor2 = studentClass.getConstructor();
//创建对象
Student student3 = (Student)constructor2.newInstance();
System.out.println(student3);
Field field1 = studentClass.getDeclaredField("password");
System.out.println(field1);
Field field = studentClass.getDeclaredField("name");
Class type = field.getType();
System.out.println(type);
int nod = field.getModifiers();
System.out.println(nod);
Field f = studentClass.getField("name");
System.out.println(f);
getField和getDeclaredField的区别
这两个方法都是用于获取字段
getField 只能获取public的,包括从父类继承来的字段。
getDeclaredField 可以获取本类所有的字段,包括private的,但是不能获取继承来的字段。 (注: 这里只能获取到private的字段,但并不能访问该private字段的值,除非加上setAccessible(true))
//getField()和getDeclaredField()都能用于访问属性字段,但是getField()只能访问public修饰的包括从
//父类继承来的,getDeclaredField()能访问所有的字段包括private,但是要访问private修饰的字段的值必须
//setAccessible(true);才能进行访问值。
//reflect方法调用
//创建一个student对象
Student stu = new Student();
//获取student 类对象
Class stuClass = stu.getClass();
//获取method对应的java类型Method
Method[] stuMethod = stuClass.getMethods();
for (Method method:stuMethod
) {
System.out.println(method);
}
Method me = stuClass.getMethod("method");
//调用方法
me.invoke(stu);