java篇26-Java匿名内部类、invoke方法、动态代理
一、匿名内部类匿名内部类一般作为方法的参数这个方法的形参为接口而实参为匿名内部类可以理解为接口的对象并且重写了接口中的方法。书写形式new接口名(){Overvide//重写方法}例如定义了一个接口Star类型为Star的引用数据类型作为方法show()的参数在调用方法show()是传递一个匿名的Star对象且重写了其中的dance方法执行结果就是执行重写的dance()的内容说明上述代码其实是省略了一般的实现接口的类的步骤因为该类只用到一次。不适用匿名内部类时的书写步骤如下。publicclassStar{publicvoiddance();}新建类实现Star接口publicclassDancerimplementsStar{Overridepublicvoiddance(){System.out.println(跳舞);}}测试publicclassMyTest{publicvoidshow(Starstar){star.dance();}publicstaticvoidmain(String[]args){StarstarnewDancer();show(star);}}说明这里只说了接口的例子其他例子参考另一篇博文《java的内部类》。二、invoke方法invoke可以理解为对象方法的另一种调用形式。先通过反射机制获取到类的方法并赋给Method对象再调用Method对象的invoke()方法invoke()方法的参数指定类的对象名称实现调用对象的方法的功能。当调用的方法没有参数时invoke的参数为一个参数为对象名称当调用的方法有一个参数时invoke的参数有两个第一个是对象名称第二个是方法实行的实参。例如:定义了一个类BigStar:使用反射机制获取了BigStar的Class对象并通过getMethod()获取了sing()方法为methodSingmethodSing.invoke()的作用是调用bigStar对象的sing()方法且方法的参数为好运来执行结果如下三、动态代理要先学反射机制不然看不懂动态代理的特点是可以无侵入式的给代码增加额外的功能。一般是通过“自定义的代理类”来管理“指定类”被代理类的方法的执行这里的“管理方法的执行”实质是在方法执行前添加一些代码表现为方法执行的功能增加了。java.lang.reflect.Proxy类提供了为对象产生代理对象的方法补充参数一说明创建的代理类的字节码文件是通过类加载器ClassLoader加载到内存中的书写形式为“创建的代理类名称.class.getClassLoader()”。参数二说明写法为new Class[]{接口1名称.class,接口2名称.class,…}这样书写之后就可以将所有接口中的方法交给该代理类。参数三说明参数三为匿名内部类形式为newInvocationHandler(Objectproxy,Methodmethod,Object[]args)throwsThrowable{//自定义内容}类InvocationHandler的匿名对象的第一个属性为proxy即为代理对象第二个属性method为代理要管理的方法args为传递的要管理的方法调用时传递的参数。当通过代理对象来执行被代理对象的方法时method就是该方法args就是该方法的参数。换一种说法给“类的方法增加功能”也可以理解为“将一些功能交给代理做被代理类不管只做想做的”就像明星被代理类只负责唱歌跳舞但是场地布置、收费等工作交给工作人员代理类来完成。注意JDK的动态代理要求目标对象必须实现接口。对于无接口的类要为其创建动态代理就要使用CGLIB,CGLIB动态代理可以不用实现接口有接口也没问题CGLIB代理的生成原理是生成目标类的子类而子类是增强过的这个子类对象就是代理对象所以使用CGLIB生成动态代理要求目标类必须能够被继承而不是final的对象。CGLIB广泛运用于AOP的框架例如Spring AOP。很晕吧那就用示例说明定义一个接口Star接口中有两个方法sing()和dance()类BigStar实现了该接口并重写了两个类增加了name字段和set,get,构造器方法定义的代理类ProxyUtil该代理类的静态方法createProxy()方法的参数为BigStar对象返回值为Star接口对象其中使用了Proxy.newProxyInstance()方法创建了一个代理对象原本的返回值类型为Object强转为Star类型并返回这样就可以通过Proxy.createProxy()方法为其参数对象这里为BigStar对象bigStar创建代理即返回值Star对象star。Proxy.newProxyInstance()方法的第一个参数了解书写形式即可第二个参数为执行被代理的接口的字节码第三个参数的作用是对被代理的接口的方法增加功能注意代理类是可以对接口中所有的方法增加功能当通过代理类对象调用被代理类的方法时该方法就传给invoke()方法里的method代理类对象调用被代理类的方法时的参数传给args。会发现这里的invoke()方法有返回值实际上是method.invoke()的返回值也就是代理类对象调用被代理类的方法的返回值后面说明测试如下通过ProxyUtil.createProxy方法创建了被代理类BigStar的对象bigStar的代理对象proxy类型为Star当调用proxy.dance()方法时Proxy.new ProxyInstance()中的new InvoactionHandler(){}创建的匿名类会发挥作用将要执行被代理对象bigStar的dance()方法并在执行之前添加一些操作先通过判断得出执行的是被代理对象bigStar的dance()方法上面的if-else语句然后执行“System.out.println(“准备场地收钱”)”再真正执行dance()方法通过method.invoke(bigStar,args)实现增加了功能。补充1.之前提到Proxy.new ProxyInstance()中的new InvoactionHandler(){}创建的匿名对象中重写的invoke()方法的返回值这里通过例子展示功能将代理类执行的方法proxy.sing()的结果返回值就是被代理类结果的返回值。结语我承认我的讲述很绕很难理解能理解的人可以表扬一下自己的理解能力。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2467411.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!