一、反射的概述
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
反射就是把java类中的各种成分映射成一个个的Java对象
例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。
二、反射的使用
直接上代码
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; public class ReflectDemo { private String name; int age; @Override public String toString() { return "ReflectDemo{" + "name=‘" + name + ‘\‘‘ + ", age=" + age + ‘}‘; } public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException { //给对象的属性赋值 包括私有和共有 都可以赋值 ReflectDemo reflectDemo = new ReflectDemo(); reflectDemo.setProperty(reflectDemo,"name","你大爷"); reflectDemo.setProperty(reflectDemo,"age",2222); System.out.println(reflectDemo); //获取指定类的字节码文件 Class c = Class.forName("com.bytech.cn.dao.domain.AdminPo"); //通过字节码文件 所有的公共构造方法 Constructor[] constructors = c.getConstructors(); for (Constructor constructor : constructors){ System.out.println(constructor); } //通过字节码文件 获取所有的所有构造方法 Constructor[] constructors1 = c.getDeclaredConstructors(); //通过字节码文件 获取无参构造方法 Constructor constructor2 = c.getConstructor(); System.out.println(constructor2); //1.获取反射去获取该构造方法 并使用 Class c3 = Class.forName("com.bytech.cn.dao.domain.AdminPo"); //2.获取带参构造器 Constructor constructor4 = c.getConstructor(Integer.class,String.class,String.class); //获取这个对象 Object obj = constructor4.newInstance(2222,"222","222"); System.out.println(obj); //获取私有的构造方法 Constructor constructor5 = c.getDeclaredConstructor(String.class,String.class); //暴力访问 constructor5.setAccessible(true); //创建对象 Object obj2 = constructor5.newInstance("aa","bb"); System.out.println("=============="); System.out.println(obj2); //获取成员变量 并给成员变量赋值 Field adminFiled = c3.getDeclaredField("adminName"); adminFiled.setAccessible(true); adminFiled.set(obj,"管理员姓名"); System.out.println("~~~~~~~~~~~~~~~~~~~~~"); System.out.println(obj); //所有的方法访问 //public Menthod getMothod (String name ,Class<?> ...parmeterTypes) //第一个参数表示的是方法名,第二个参数表示的是方法的参数class类 Method m1 = c.getMethod("方法名字"); /*public Object invoke(Object obj,Object ...args)*/ m1.invoke(obj);//调用obj对象的m1方法 System.out.println("============"); Method m2 = c.getMethod("方法名字",String.class); m2.invoke(obj,"hello"); System.out.println("================="); Method m3 = c.getMethod("getString",String.class,Integer.class); Object objectString = m3.invoke(obj,"hello",100); Method m4 = c.getDeclaredMethod("function"); m4.setAccessible(true); m4.invoke(obj); //我给你ArrayList<Integer>的一个对象 ,我想在这个集合中添加一个字符串数据,如何实现呢*/ //解答开始 ArrayList<Integer> array = new ArrayList<>(); array.add(11); Class arrayClass1 = array.getClass(); Method m = arrayClass1.getMethod("add",Object.class); m.invoke(array,"你好"); System.out.println(array); System.out.println(".............................................."); Class arrayClass = Class.forName("java.util.ArrayList"); Constructor constructor = arrayClass.getConstructor(); Object object = constructor.newInstance(); Method methodArray = arrayClass.getMethod("add",Object.class); methodArray.invoke(object,"hello ni da ye"); System.out.println(object); //解答完毕 } public void setProperty(Object obj,String filedName,Object filedValue) throws NoSuchFieldException, IllegalAccessException { Class c = obj.getClass(); Field field = c.getDeclaredField(filedName); field.setAccessible(true); field.set(obj,filedValue); } }
三、实现一个动态代理
public interface UserDao { void add(); void delete(); void update(); void select(); }
public class UserDaoImpl implements UserDao { @Override public void add() { System.out.println("添加功能"); } @Override public void delete() { System.out.println("删除功能"); } @Override public void update() { System.out.println("修改功能"); } @Override public void select() { System.out.println("查询功能"); } }
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class MyInvocationHandler implements InvocationHandler { private Object target; //目标对象 public MyInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("权限校验"); Object result = method.invoke(target,args); System.out.println("日志记录"); return result; //返回的是代理对象 } }
import java.lang.reflect.Proxy; public class TestProxy { public static void main(String[] args) { UserDao ud = new UserDaoImpl(); ud.add(); ud.delete(); ud.select(); ud.update(); System.out.println("----------------"); //我们要创建一个动态代理类 //proxy类中有一个方法 可以创建动态代理对象 //public static Class<?> getProxyClass(ClassLoader loader,Class<?>... interfaces)throws IllegalArgumentException MyInvocationHandler handler = new MyInvocationHandler(ud); UserDao userDaoProxy = (UserDao)Proxy.newProxyInstance(ud.getClass().getClassLoader(),ud.getClass().getInterfaces(),handler); userDaoProxy.update(); userDaoProxy.select(); userDaoProxy.delete(); userDaoProxy.add(); } }
这样就实现了一个动态代理。。