https://v.youku.com/v_show/id_XMzMzMjA0NDAzNg==.html?spm=a2h0k.11417342.soresults.dposter
什么是反射
Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,就能够调用它的任意方法和属性;并且能够改变它的属性。而这也是java被视为动态语言的一个关键性质。
反射能做什么
我们知道反射机制允许程序在运行时取得任意一个已知名称的class的内部信息,包括期modifiers(修饰符),fields(属性),methods(方法)等,并可于运行时改变fields内容或调用methods。那么我们更可以灵活的编写代码,代码可以在运行时装配,无需在组件之间进行源代码链接,降低代码的耦合度;还有动态代理的实现等等;但是需要注意的是反射使用不当会造成很高的资源消耗!
反射是基于什么实现的?或者说反射的源头
源头的字节码对象(class对象)
使用反射,一定是基于字节码对象,所以第一步一定是获得字节码对象,怎么获得?一共三种方法
使用频率3>2>1
通过反射机制创建类的对象的快捷方式
第一种
//1.获得字节码对象
Class clazz1 = Class.forName(".........");
//2.直接使用字节码对象创建类的实例
Object obj = clazz1.newInstance();
cookies
我们注意到定义一个类,**如果我们不给定构造方法,那么这个类会有一个公共的无参的构造方法,如果我们给定了构造方法,那么就没有默认的构造方法,**这点一定要注意
Object obj = clazz1.newInstance();这个方法它底层依赖的是无参的构造方法,换句话说,类中没有默认无参的构造方法,那么就不能用这种方式。
第二种
通过字节码对象获取constructor对象来创建类的对象
//1.获得Constructor对象
Constructor[] constructors = clazz1.getConstructors()
获取所有的构造方法对象,返回数组,但是只能获得public的构造方法,如果想获得所有的构造方法,使用getDeclaredConstructor()方法
//如何获取单个的构造方法
Constructor constructor1 = clazz1.getConstructor();//里面带指定构造方法的参数
//用构造器对象来创建类的对象
Object obj1 = constructor1.newInstance();
//如何获取单个的带参数的构造方法
//注意是指定类型的字节码文件,字节码就是.class,构造方法的参数是int类型
Constructor constructor2 = clazz1.getConstructor(int.class);
//获取实例
Object obj2 = constructor2.newInstance(10);
能用私有的构造方法创建对象吗?
这里我们想到了单例模式,用我们正常情况下去new一个对象是不行的,会提示方法不可见,因为是加了private
但是用反射就可以,就可以用私有的构造方法创建一个实例
//要获得单个私有修饰符的构造器对象
//私有构造方法里面有两个类型的参数
Constructor constructor3 = clazz1.getDeclaredConstructor(int.class,String.class);
//但是这里仍然会报错,因为是私有的构造方法,得到我的人,却得不到我的心
Object obj = constructor3.newInstance(10,"adf");
//暴力访问,设置成可以访问的
constructor3.setAccessible(true);
Object obj = constructor3.newInstance(10,"adf");
上面是访问构造方法constructor,如果要访问成员方法method该怎么办呐?跟上面一样,getMethod(),getDeclaredMethod()
Class clazz = Student.class;
//加declared获取私有方法
Method method = clazz.getDeclaredMethod("方法名称",方法参数的字节码String.class)
如何执行方法?
两个参数,第一个是对象,第二个是具体的类型
method.invoke(clazz.newInstance,"avc")
这里也有可能方法是私有的无法访问,加暴力访问权限onstructor3.setAccessible(true);