Java基础之反射及动态代理,反射实现工厂模式
2017-05-25 14:04
691 查看
一,先看一下反射的概念: 主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。 反射是Java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接。但是反射使用不当会成本很高! 看概念很晕的,继续往下看。 二,反射机制的作用: 1,反编译:.class-->.java 2,通过反射机制访问java对象的属性,方法,构造方法等; 这样好像更容易理解一些,下边我们具体看怎么实现这些功能。 三,在这里先看一下sun为我们提供了那些反射机制中的类: java.lang.Class; java.lang.reflect.Constructor; java.lang.reflect.Field; java.lang.reflect.Method; java.lang.reflect.Modifier; 四。从例子看常用的用法: package reflect; import java.io.Serializable; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; public class ReflectTest implements Serializable { /** * */ private static final long serialVersionUID = 6957472993081091730L; public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException { Class<?> class1 = null; Class<?> class2 = null; Class<?> class3 = null; class1 = Class.forName("reflect.ReflectTest");//实例化Class类对象-1 class2 = new ReflectTest().getClass();//实例化Class类对象-2 class3 = ReflectTest.class;//实例化Class类对象-3 Class<?> parentClass = class1.getSuperclass();//获得父类 Class<?> intes[] = class1.getInterfaces();//获得所有接口 Class<?> class4 = Class.forName("reflect.User");//完整路径的类名,包括package name User user1 = (User) class4.newInstance();// create a user through reflect user1.setUsername("lilong"); Constructor<?> cons[] = class4.getConstructors(); ReflectTest reflectTest = new ReflectTest(); System.out.println("通过一个对象获得完整的包名和类名:" + reflectTest.getClass().getName()); System.out.println("___________________________"); System.out.println("类名称 " + class1.getName()); System.out.println("类名称 " + class2.getName()); System.out.println("类名称 " + class3.getName()); System.out.println("___________________________"); System.out.println("class1的父类是:"+ parentClass.getName()); System.out.println("class1实现的接口有:"); for(int i=0; i<intes.length; i++){ System.out.println((i+1) + ":" + intes[i].getName()); } System.out.println("___________________________"); System.out.println("username : " + user1.getUsername()); for(int i =0; i<cons.length; i++){ Class<?> clazzs[] = cons[i].getParameterTypes(); //取得各个参数类型构成的Class数组 System.out.print("cons[" + i + "] ("); for(int j=0; j<clazzs.length; j++){ if(j == clazzs.length-1) System.out.print(clazzs[j].getName()); else { System.out.print(clazzs[j].getName() + ","); } } System.out.println(")"); } System.out.println("___________________________"); Class<?> class5 = Class.forName("reflect.Student"); System.out.println("===============本类属性==============="); Field[] fields = class5.getDeclaredFields(); //该类声明的属性 for(int i=0; i<fields.length; i++){ String mo = Modifier.toString(fields[i].getModifiers()); //权限修饰符 Class<?> type = fields[i].getType();// 属性类型 System.out.println(mo + " " + type.getName() + " " + fields[i].getName() + ";"); } System.out.println("==========实现的接口或者父类的属性=========="); Field[] fields2 = class5.getFields(); //获得实现的接口或者父类的属性 for(int i=0; i<fields2.length; i++){ String mo = Modifier.toString(fields2[i].getModifiers()); Class<?> type = fields2[i].getType(); System.out.println(mo + " " + type.getName() + " " + fields2[i].getName() + ";"); } System.out.println("___________________________"); System.out.println("获取某个类的全部方法"); Class<?> class6 = Class.forName("reflect.Student"); Method[] method = class6.getMethods(); for(int i=0; i<method.length; i++){ Class<?> returnType = method[i].getReturnType(); Class<?>[] param = method[i].getParameterTypes(); int temp = method[i].getModifiers(); System.out.print(Modifier.toString(temp) + " " + returnType.getName() + " " + method[i].getName()+"("); for(int j=0; j<param.length; j++){ System.out.print(param[j].getName() + " arg" + j); if(j < param.length -1){ System.out.print(","); } } Class<?>[] exce = method[i].getExceptionTypes(); if(exce.length > 0){ System.out.print(") throws "); for(int k=0; k< exce.length; k++){ System.out.print(exce[k].getName() + ""); if(k < exce.length -1){ System.out.print(","); } } }else { System.out.print(")\n"); } System.out.println(); } System.out.println("___________________________"); System.out.println("通过反射机制调用某个类的方法"); Class<?> class7 = Class.forName("reflect.Student"); Method method2 = class7.getMethod("print"); //调用无参方法 Method method3 = class7.getMethod("print2", String.class);//调用有参方法 try { method2.invoke(class7.newInstance()); method3.invoke(class7.newInstance(), "i am a student too."); } catch (IllegalArgumentException | InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("___________________________"); System.out.println("通过反射机制操作某个类的属性"); Class<?> class8 = Class.forName("reflect.Student"); Object object = class8.newInstance(); Field field; try { field = class8.getDeclaredField("password"); field.setAccessible(true); field.set(object, "lilong123"); System.out.println("password is " + field.get(object)); } catch (NoSuchFieldException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("___________________________"); System.out.println("反射机制的动态代理"); MyInvocationHandler demo = new MyInvocationHandler(); Subject sub = (Subject) demo.bind(new RealSubjec());// 接口变量指向? String info = sub.say("roolback", 20); System.out.println(info); System.out.println("___________________________"); } } class User implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private String username; public User() { this.username = "lilong"; } public User(String username) { this.username = username; } public String getUsername() { return username; 4000 } public void setUsername(String username) { this.username = username; } } class Student extends User { /** * */ private static final long serialVersionUID = 1L; private String password; public Student() { super(); // TODO Auto-generated constructor stub } public Student(String password) { super(); this.password = password; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public void print(){ System.out.println("i am a student."); } public void print2(String str) { System.out.println(str); } } interface Subject{ public String say(String name, int age); } class RealSubjec implements Subject{ @Override public String say(String name, int age) { return name + " " + age; } } class MyInvocationHandler implements InvocationHandler{ private Object obj = null; /** * 在java中有三种类类加载器。 * * 1)Bootstrap ClassLoader 此加载器采用c++编写,一般开发中很少见。 * * 2)Extension ClassLoader 用来进行扩展类的加载,一般对应的是jrelibext目录中的类 * * 3)AppClassLoader 加载classpath指定的类,是最常用的加载器。同时也是java中默认的加载器。 * * 如果想要完成动态代理,首先需要定义一个InvocationHandler接口的子类,已完成代理的具体操作。 * 动态代理的代理类是实现了一个InvocationHandler的接口,我们通过reflect.Proxy的类的newProxyInstance方法就可以得到这个接口 的实例,然后再来作为参数传递进去,这里每一个在代理类上处理的东西也会被重定向到调用处理器上。 * @author * */ public Object bind(Object obj){ this.obj = obj; return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object temp = method.invoke(this.obj, args); return temp; } } 用反射实现工厂模式: package reflect; public class ReflectTest2 { public static void main(String[] args) { Fruit fruit1 = Factory.getInstance("reflect.Apple"); Fruit fruit2 = Factory.getInstance("reflect.Orange"); fruit1.eat(); fruit2.eat(); } } interface Fruit{ public void eat(); } class Apple implements Fruit{ @Override public void eat() { System.out.println("Apple"); } } class Orange implements Fruit{ @Override public void eat() { System.out.println("Orange"); } } /** * 对于普通的工厂模式当我们在添加一个子类的时候,就需要对应的修改工厂类。 当我们添加很多的子类的时候,会很麻烦。 * Java 工厂模式可以参考 * http://baike.xsoftlab.net/view/java-factory-pattern * * 现在我们利用反射机制实现工厂模式,可以在不修改工厂类的情况下添加任意多个子类。 * * 但是有一点仍然很麻烦,就是需要知道完整的包名和类名,这里可以使用properties配置文件来完成。 * * java 读取 properties 配置文件 的方法可以参考 * http://baike.xsoftlab.net/view/java-read-the-properties-configuration-file * * @author xsoftlab.net */ class Factory{ public static Fruit getInstance(String ClassName) { Fruit fruit = null; try { fruit = (reflect.Fruit) Class.forName(ClassName).newInstance(); } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { e.printStackTrace(); } return fruit; } }
相关文章推荐
- 模拟实现Struts拦截器-蕴含着代理模式,AOP,工厂模式,依赖注入,Java 反射,动态构造等机制
- java语言基础入门——用反射实现动态代理
- 15. JAVA 反射机制 Part 2(动态代理、类的生命周期、工厂设计模式) ----- 学习笔记
- Java基础 - 类的加载,类加载器,反射,动态代理,模板设计模式,JDK5新特性,枚举(类),JDK1.7新特性
- 反射实现 AOP 动态代理模式
- 反射实现AOP 动态代理模式(Spring AOP 的实现原理)
- 反射实现 AOP 动态代理模式(Spring AOP 的实现 原理)
- 动态代理,工厂模式和反射技术
- 反射实现 AOP 动态代理模式(Spring AOP 的实现 原理)
- 反射实现 AOP 动态代理模式(Spring AOP 的实现原理)
- 反射实现 AOP 动态代理模式(Spring AOP 的实现 原理)
- 反射实现 AOP 动态代理模式(Spring AOP 的实现 原理)
- 反射实现 AOP 动态代理模式(Spring AOP 的实现 原理)
- Java反射之JDK动态代理实现简单AOP
- 利用Java的反射与代理实现IOC模式
- 反射实现 AOP 动态代理模式(Spring AOP 的实现 原理)
- 用Java动态代理实现委托模式
- 反射实现 AOP 动态代理模式(Spring AOP 的实现 原理)
- 反射实现 AOP 动态代理模式(Spring AOP 的实现 原理)
- 反射实现 AOP 动态代理模式(Spring AOP 的实现 原理)