概述:反射机制允许程序在运行时借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性和方法。加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息。 正常方式是通过new实例化一个对象,反射是根据实例化对象获得该实例类的信息。
一、通过反射获取类信息的方式有三种:
- 通过Class.forName方法,传入类完整包路径 Class c1 = Class.forName("com.lcy.reflection.User");
- 直接通过类.class获取 Class c2 = User.class;
- 通过对象实例获取 User user = new User(); Class c3 = user.getClass();
二、反射提供的主要API:
java.lang.Class : 代表一个类
java.lang.reflect.Method : 代表类的方法
java.lang.reflect.Field : 代表类的成员变量
java.lang.reflect.Constructor : 代表类的构造器
三、有了Class可以做什么:
可以获得类的属性
Field[] fields = c1.getFields(); //找到public属性 fields = c1.getDeclaredFields(); //找到全部属性
可以获得指定属性的值
Field name = c1.getDeclaredField("name");
可以获得类的方法
Method[] methods = c1.getMethods(); //找到public方法 methods = c1.getDeclaredMethods(); //找到所有方法
可以获得指定的方法
Method getName = c1.getMethod("getName", null); Method setName = c1.getMethod("setName", String.class);
可以获得构造器
Constructor[] constructors = c1.getConstructors(); //找到public构造器 constructors = c1.getDeclaredConstructors(); //找到所有构造器
可以获得指定的构造器
Constructor declaredConstructor = c1.getDeclaredConstructor( int.class,String.class,String.class);
四、通过反射对Class进行操作:
构造对象:
User user = (User)c1.newInstance(); //使用默认构造方法 Constructor constructor = c1.getDeclaredConstructor(int.class, String.class, String.class); //使用指定构造器 User user2 = (User) constructor.newInstance(1, "张三", "123");
调用普通方法
Method setName = c1.getDeclaredMethod("setName", String.class); setName.invoke(user,"张三");
操作属性:
Field name = c1.getDeclaredField("name"); name.setAccessible(true); name.set(user2,"张三");
五、设计模式的几个原则:
静态代理违反了开闭原则,所以引入了动态代理,动态代理使用了Proxy和InvocationHandler,Proxy负责为每个接口创建动态代理类,InvocationHandler负责对某个代理方法实现具体的增强。