JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象
获取Class对象的方式
//通过创建对象获取字节码对象
1,Person p = new Person();
Class clazz1 = p.getClass();
//任意数据类型都具备一个class静态属性
2,Class clazz2 = Person.class;
//按类名作为字符串传递给Class类中的static方法forName即可
3,Class clazz3 = Class.forName("Person");
获取所有方法
Method[] getMethods()
Method[] getDeclaredMethods()
获取单个方法
Method getMethod("方法名","方法参数")没有参数就传null
我们拿到了该方法怎么运行呢?Method类中有invoke方法,因为invoke里面接收的是
对象的参数,对象又从哪里来呢?通过Class类中有一个newInstance() 创建此 Class
对象所表示的类的一个新实例。
Object obj = clazz.newIntance();
Object invoke(Object obj, Object... args)
对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。
Method getDeclaredMethod
Class
.class文件加载到内存中就是一个Class对象
获取Class对象的方式有3种:
Class.forName("")
类名.class
对象.getClass()
Constructor
Class类的newInstance()方法是使用该类无参的构造函数创建对象, 如果一个类没有无参的构造函数, 就不能这样创建了
可以调用Class类的getConstructor(String.class,int.class)方法获取一个指定的构造函数
然后再调用Constructor类的newInstance("张三",20)方法创建对象
Field
Class.getField(String)方法可以获取类中的指定字段(可见的), 如果是私有的可以用getDeclaedField("name")方法获取
通过set(obj, "李四")方法可以设置指定对象上该字段的值, 如果是私有的需要先调用setAccessible(true)设置访问权限
用获取的指定的字段调用get(obj)可以获取指定对象中该字段的值
Method
Class.getMethod(String, Class...) 和 Class.getDeclaredMethod(String, Class...)方法可以获取类中的指定方法
调用invoke(Object, Object...)可以调用该方法
Class.getMethod("eat") invoke(obj) Class.getMethod("eat",int.class) invoke(obj,10)
总结:
反射主要就是通过字节码文件也就是class文件调用类中的方法