反射
反射详解
1 | * 常用相关api: |
疑问:
什么时候用反射?
编译时期确定不了用哪个类的对象 (servlet 中的体现,根据前端请求确认用户执行那些操作(例如:登陆,注册)创建相关对象)
1)new +构造器
2)类本身或工具类提供的静态方法创建对象
3)反射
获取Class实例的几种方式
方式一:调用运行时类的属性
1 | Class<Person> class1 = Person.class; |
方式二:通过运行时对象
1 | Person p1=new Person(); |
方式三:调用Class的静态方法 (推荐)
1 | Class class3 = Class.forName("cn.itcast.base.Person");//类的全类名 |
方式四 调用类的加载器加载ClassLoader (了解)
1 | ClassLoader classLoader = ReflexTest.class.getClassLoader(); |
反射操作
Person基类:
1 | public class Person { |
通过反射Person的操作:
1)通过反射创建Person对象
1 | Class<Person> personClass = Person.class; |
2)通过反射调用对象指定的方法,属性
1 | Field age = personClass.getDeclaredField("age"); |
3)调用私有构造器
1 | Constructor<Person> cons1 = personClass.getDeclaredConstructor(String.class); |
4)调用私有属性
1 | Field name = personClass.getDeclaredField("name"); |
5)调用私有方法
1 | Method hello = personClass.getDeclaredMethod("hello"); |
代理
代理设计模式原理: 使用一个代理将对象包装起来,然后该代理类对象取代原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用到原始对象
静态代理
代理类和被代理类在编译期间都确定下来。
接口定义:
1 | interface ClohtFactory{ |
定义代理类:
1 | class ProxyClothFactory implements ClohtFactory{ |
被代理类:
1 | class NikeClothFactory implements ClohtFactory { |
进行静态代理测试:
1 | public class StaticProxyTest { |
动态代理
在程序运行时确定代理对象,通过反射获得运行时类创建代理类。
接口定义:
1 | interface Human{ |
被代理类:
1 | class SuperMan implements Human{ |
实现动态代理需要解决问题:
1)如何根据加载到内存中的被代理类,动态的创建一个代理类及其对象?
2)当通过代理类的对象调用方法时,如何动态的取调用被代理类的同名方法?
1 | class ProxyFactory{ |
构建 MyInvocationHandler实现InvocationHandler接口
1 | class MyInvocationHandler implements InvocationHandler{ |
动态代理测试:
1 | public static void main(String[] args) { |