Java匿名内部类、invoke方法、动态代理

news2024/11/28 13:32:01

一、匿名内部类
匿名内部类一般作为方法的参数,这个方法的形参为接口,而实参为匿名内部类(可以理解为接口的对象)并且重写了接口中的方法。
例如:
定义了一个接口Star:
在这里插入图片描述
类型为Star的引用数据类型作为方法show()的参数,在调用方法show()是传递一个匿名的Star对象且重写了其中的dance方法,执行结果就是执行重写的dance()的内容:
在这里插入图片描述
二、invoke方法
invoke可以理解为对象方法的另一种调用形式。先通过反射机制获取到类的方法并赋给Method对象,再调用Method对象的invoke()方法,invoke()方法的参数指定类的对象名称,实现调用对象的方法的功能。
当调用的方法没有参数时invoke的参数为一个(参数为对象名称),当调用的方法有一个参数时invoke的参数有两个(第一个是对象名称,第二个是方法实行的实参)。
例如:
定义了一个类BigStar:
在这里插入图片描述
使用反射机制获取了BigStar的Class对象,并通过getMethod()获取了sing()方法为methodSing,methodSing.invoke()的作用是调用bigStar对象的sing()方法且方法的参数为"好运来":
在这里插入图片描述
执行结果如下:
在这里插入图片描述
三、动态代理(要先学反射机制不然看不懂)
动态代理的特点是可以无侵入式的给代码增加额外的功能。一般是通过“自定义的代理类”来管理“指定类”(被代理类)的方法的执行,这里的“管理方法的执行”实质是在方法执行前添加一些代码,表现为方法执行的功能增加了。
java.lang.reflect.Proxy类提供了为对象产生代理对象的方法:
在这里插入图片描述
补充:
参数一说明:创建的代理类的字节码文件是通过类加载器(ClassLoader)加载到内存中的,书写形式为“创建的代理类名称.class.getClassLoader()”。
参数二说明:写法为"new Class[]{接口1名称.class,接口2名称.class,…}",这样书写之后就可以将所有接口中的方法交给该代理类。
参数三说明:参数三为匿名内部类,形式为:

new InvocationHandler(Object proxy, Method method, Object[] args) throws Throwable{
//自定义内容
}

类InvocationHandler的匿名对象的第一个属性为proxy即为代理对象,第二个属性method为代理要管理的方法,args为传递的要管理的方法调用时传递的参数。当通过代理对象来执行被代理对象的方法时,method就是该方法,args就是该方法的参数。
换一种说法,给“类的方法增加功能”也可以理解为“将一些功能交给代理做,被代理类不管,只做想做的”,就像明星(被代理类)只负责唱歌跳舞,但是场地布置、收费等工作交给工作人员(代理类)来完成。
很晕吧,那就用示例说明:
定义一个接口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/620413.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于docker中Nacos启动成功访问不了的情况

书接上回,这段时间在忙学成在线的微服务项目,上次出现了IP修改的问题,有了一定的解决方案,复制别人的虚拟机后如何修改IP_SSSEdward的博客-CSDN博客。 这次docker正常启动了,但是出现了访问不了的情况,但是…

短视频矩阵系统源码打包附赠分享

矩阵系统源码主要有三种框架:Spring、Struts和Hibernate。Spring框架是一个全栈式的Java应用程序开发框架,提供了IOC容器、AOP、事务管理等功能。Struts框架是一个MVC架构的Web应用程序框架,用于将数据模型、Web应用程序的用户界面和控制器逻…

【备战秋招】Java异常处理

Java程序在执行过程中所发生的异常事件可分为两类: Error:Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源 耗尽等严重情况。 比如:StackOverflowError和OOM。一般不编写针对性的代码进行处理。 Exception: 其它因编程错…

使用pytorch进行FFT和STFT

首先,我们定义一个波形,幅值分别为20和38,频率为2和13: y 20 sin ⁡ ( 2 π 2 x ) 38 sin ⁡ ( 2 π 13 x ) y20 \sin (2\pi \times 2x)38\sin (2\pi \times 13x) y20sin(2π2x)38sin(2π13x) 采样频率为200Hz,采…

十四届蓝桥杯省赛CB

hinhin可否不要老&#xff0c;令创新高 A 日期统计B 01 串的熵C 冶炼金属D: 飞机降落E: 接龙数列F: 岛屿个数G: 子串简写H: 整数删除I: 景区导游J: 砍树 A 日期统计 #include <bits/stdc.h> using namespace std; #define int long long int #define pii pair<int,int…

VR云探校:解锁不一样的视角,“沉浸式”打卡校园

仲夏六月&#xff0c;又是一年高考时&#xff0c; 高考首战已经正式拉开帷幕&#xff0c; 超千万考生赴考&#xff0c;更有千万考生家长花式赴考。 少年的你披星戴月走过的路&#xff0c;终将会繁华遍地&#xff0c;今天VR全景就为千万考生和家长解锁不一样的视角&#xff0…

java观察者模式例子

观察者模式&#xff1a; 是一种常用的设计模式&#xff0c;它定义了一种一对多的关系&#xff0c;让多个观察者对象同时监听某一个主题对象&#xff0c;当主题对象状态发生变化时&#xff0c;它的所有观察者都会收到通知并且自动更新。 在观察者模式中&#xff0c;主题对象通…

Minicap编译及简单使用

什么是MiniCap 官方说法&#xff1a;Minicap提供了一个套接字接口&#xff0c;用于从Android设备流式传输实时屏幕捕获数据。它旨在用作更大程序中的组件&#xff0c;因此仅凭其本身并不是非常有用。例如&#xff0c;它在STF中用于远程控制。 个人理解&#xff1a;Minicap是用…

如何检查 Android 设备是否支持 Widevine DRM

想知道您的 Android 设备是否可以流式传输来自 Netflix 和 Amazon Prime Video 的高清视频&#xff1f;这是检查 Widevine DRM 支持的方法&#xff01; 许多流媒体服务&#xff0c;如 Netflix、Disney、Hulu 等&#xff0c;使用各种类型的数字版权管理 (DRM) 来保护其内容不被…

VulnHub项目:Hogwarts dobby

靶机地址&#xff1a;Hogwarts: Dobby ~ VulnHub 哈利波特也是初中时候最喜欢的电影~Dobby多比是马尔福加的奴隶精灵&#xff0c;出现在第二部密室中&#xff0c;后来被哈利波特的袜子所拯救&#xff0c;成为了一只快乐自由的小精灵&#xff0c;最后它在死亡圣器中&#xff0c…

keil从非0x08000000地址调试STM32单片机程序方法

在使用stm32单片机的串口IAP升级功能时&#xff0c;需要调试bootloader程序和app程序&#xff0c;一般bootloader的程序都是从0x08000000地址开始运行的&#xff0c;使用keil软件可以直接进行仿真&#xff0c;但是如果调试app程序的话&#xff0c;由于它不是从0x08000000地址开…

Java程序判断是否是回文

1 问题 利用java程序判断是否是回文。 2 方法 利用函数库&#xff0c;将输入的字符串倒置&#xff0c;看倒置后的字符串和原来的字符串是否一样&#xff0c;然后得出结论。 package practice; import java.util.Scanner; public class Huiwen { public static void main(St…

【MySQL数据库 | 第五篇】DDl操作数据库

目录 &#x1f914;DDL介绍&#xff1a; &#x1f914;语法详解&#xff1a; 1.查询&#xff1a; 1.查询所有数据库&#xff1a; 示例&#xff1a;查询自带数据库 2.查询当前数据库&#xff1a; 2.创建&#xff1a; 示例&#xff1a;创建一个名字叫做itcast的数据库&…

第一期丨INTERSPEECH 2023 论文预讲会

INTERSPEECH 2023 论文预讲会是由CCF语音对话与听觉专委会、语音之家主办&#xff0c;旨在为学者们提供更多的交流机会&#xff0c;更方便、快捷地了解领域前沿。活动将邀请 INTERSPEECH 2023 录用论文的作者进行报告交流。 INTERSPEECH 2023 论文预讲会第一期邀请到清华大学和…

【新版】系统架构设计师 - 系统工程与信息系统基础

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 文章目录 架构 - 系统工程与信息系统基础考点摘要系统工程概念系统工程方法生命周期阶段及方法 信息系统诺兰模型信息系统的生命周期信息系统的建设原则信息系统的开发方法信息系统的分类信息化系统业务处理系统【…

【高危】Apache Cassandra 存在越权漏洞导致远程命令执行

漏洞描述 Apache Cassandra 是 Apache 基金会的一个分布式 Nosql 数据库。 Apache Cassandra 的受影响版本中&#xff0c;由于没有对JMX/nodetool权限的用户做限制&#xff0c;当启动FQL/Audit日志时&#xff0c;拥有 JMX/nodetool 权限的攻击者可以以 cassandra 的身份权限执…

QMediaPlayer 打包解码器注意事项

程序打包注意事项 如果需要把我们的程序进行打包&#xff0c;给客户安装使用&#xff0c;那么还需要引导客户额外安装LAVFilters&#xff0c;显得比较麻烦。接下来&#xff0c;介绍&#xff0c;如何将解码器打包进安装包。 1、QMediaPlayer找到解码器的原理 先来看看解码器&am…

Android 各版本特性

一&#xff1a;介绍 我们可以看到Android版本对应的Api版本 二&#xff1a;Android 6.0 &#xff08;API 23&#xff09; Google I/O 2015大会如约已于2015年5月28日举行。在发布会上代号为“Marshmallow&#xff08;棉花糖&#xff09;”的安卓6.0系统正式推出。 Android …

LVS简介及LVS-NAT负载均衡群集的搭建(要像记得回家的路一样记得理想和远方)

文章目录 一、LVS群集的简介1.群集的含义和应用场景2.性能扩展方式群集的分类负载均衡&#xff08;LB&#xff09;高可用&#xff08;HA&#xff09;高性能运算&#xff08;HPC&#xff09; 二、LVS负载均衡群集简介及搭建1.负载均衡群集架构第一层&#xff0c;负载调度器&…

Linux - sudo:/etc/sudoers 可被任何人写

错误如下&#xff1a; sudo: /etc/sudoers 可被任何人写 sudo: 没有找到有效的 sudoers 资源&#xff0c;退出 sudo: 无法初始化策略插件 需求就是除了root账号&#xff0c;别的账号也能执行mkdir等命令 1. 先用root把 chmod 777 /etc/sudoers 设置可修改 2. 添加一条 xxx…