首先声明java中反射的定义,概念,与作用。
java中的反射可以直接获取类的属性和方法,从功能上来讲,反射与直接new一个新的对象并没有什么不同。
但是从灵活程度上来讲,反射可以更灵活的构造程序,这种灵活框架系统层面上。
以框架举例,一个框架的开发者,并不知道框架的使用者会写什么class和method来进行使用者自身业务需求的开发,那么框架的开发者也不可能得知使用者到底有什么class,这就造成了开发者在进行框架开发时的困难,无法得知类的包和名,便无法直接通过new来新建并操纵这个类。
建立在这种困难与需求之上,我们就可以使用反射,通过传入一个string的完整包名和类名,通过装载器对这个类进行装载,实现这个类的各种属性与方法。同时我们还可以利用反射的机制,来绕过类的私有安全检查,直接调用类的private或者protect方法。
示例代码:
java中的反射可以直接获取类的属性和方法,从功能上来讲,反射与直接new一个新的对象并没有什么不同。
但是从灵活程度上来讲,反射可以更灵活的构造程序,这种灵活框架系统层面上。
以框架举例,一个框架的开发者,并不知道框架的使用者会写什么class和method来进行使用者自身业务需求的开发,那么框架的开发者也不可能得知使用者到底有什么class,这就造成了开发者在进行框架开发时的困难,无法得知类的包和名,便无法直接通过new来新建并操纵这个类。
建立在这种困难与需求之上,我们就可以使用反射,通过传入一个string的完整包名和类名,通过装载器对这个类进行装载,实现这个类的各种属性与方法。同时我们还可以利用反射的机制,来绕过类的私有安全检查,直接调用类的private或者protect方法。
示例代码:
<span style="white-space:pre"> </span>ClassLoader classLoader = Thread.currentThread().getContextClassLoader();<span style="white-space:pre"> </span>//获得当前的线程
Class clazz = classLoader.loadClass("com.invoker.study.Car");<span style="white-space:pre"> </span>//你想加载的类名 必须要有完整的路径名
Car car = (Car) clazz.newInstance();<span style="white-space:pre"> </span>//根据之前的类名 来获得一个新的实现
Method setBrand = clazz.getMethod("setBrand", String.class);<span style="white-space:pre"> </span>//根据之前的类型 来获得一个方法的实例
setBrand.invoke(car, "3325112");<span style="white-space:pre"> </span>//调用Method.inovke方法,来对之前的方法进行操作 这里的作用car.setBrand()相同
//通过反射方法绕过安全机制设置私有类
Field carFld = clazz.getDeclaredField("brand");<span style="white-space:pre"> </span>//通过getDeclareField方法来获得对象的一个私有属性
carFld.setAccessible(true);<span style="white-space:pre"> </span>//取消私有验证
carFld.set(car,"??");<span style="white-space:pre"> </span>//设置这个私有属性
return car;