理解Java方法增强
在实际开发中,我们往往需要对某些方法进行增强,常用的方法增强的方式有三种。
类继承 、方法覆盖
必须控制对象创建,才能使用该方式装饰者模式方法加强
必须和目标对象实现相同接口或继续相同父类,特殊构造器(传入被包装对象)动态代理
我们来编写一个案例感受一下,新建一个Java项目。
新建类Cat
public class Cat{
public void run(){
System.out.println("喵喵~一只猫在奔跑");
}
}
现在若想对该类的run()方法进行增强,第一种方法,利用类继承,方法覆盖。
编写测试代码
@Test
public void demo1(){
//方法增强的第一种途径,利用类的继承以及方法覆盖
Cat cat = new Cat(){//匿名内部类
@Override
public void run() {
//保持方法原有的功能
super.run();
//新增该方法功能
System.out.println("抓到一只老鼠");
}
};
cat.run();
}
运行测试代码

方法成功被增强了。
该种增强方法的方式必须控制对象的创建。
那么第二种增强方式就是装饰者模式,但是请注意,使用该方式增强方法是有前提的,就是必须与原对象去实现相同的接口或者继承相同的类。
演示一下。
新建一个接口ICat
interface ICat{
public void run();
}
然后新建一个装饰者CatFilter
//装饰者
class CatFilter implements ICat{
private ICat cat;//cat就是被包装的对象
//实现目标对象相同的接口
//特殊的构造方法
public CatFilter(ICat cat){
this.cat = cat;
}
public void run() {
//原有方法功能
cat.run();
//新增方法功能
System.out.println("又抓住一只老鼠");
}
}
编写测试代码
@Test
public void demo2(){
//第二种 装饰者模式 前提:必须与原对象去实现相同的接口或者继承相同的类
ICat cat = new CatFilter(new Cat());
cat.run();
}

方法被成功增强。
第三种增强方式就是动态代理,也是Java中进行方法增强最常用的方式。
原理:根据原对象在内存中构造一个代理对象,而原对象的所有方法都将去执行代理对象的invoke方法。
演示一下。
编写测试代码
@Test
public void demo3(){
final ICat cat = new Cat();//原对象
ICat catProxy = (ICat) Proxy.newProxyInstance(cat.getClass().getClassLoader(), cat.getClass().getInterfaces(), new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] objs)
throws Throwable {
//增强run方法
if(method.getName().equals("run")){
method.invoke(cat,objs);//调用原对象的方法,保留原方法的功能
//新增功能
System.out.println("抓住第三只老鼠");
}
return null;
}
});
catProxy.run();
}
运行测试代码

方法被成功增强。
以上便是Java方法增强的三种方式。
理解Java方法增强的更多相关文章
- 深入理解 Java 方法
方法(有的人喜欢叫函数)是一段可重用的代码段.
- Java中增强一个类的几种方法
今天有人问我怎么增强一个类的功能.博客刚好没东西,今天就讲讲增强类. 增强的手段有三种类型: 1.继承或者实现接口:特点是被增强对象不能变,增强的内容不能变. 2.装饰着模式:特点是被增强对象可变,但 ...
- 深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)
作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-language- ...
- 理解JAVA - 面向对象(object) - 属性,方法
理解JAVA - 面向对象(object) - 属性,方法 多态的体现: 向上造型,父类接收子类对象:向上造型: 从父类角度看不到子类独有的方法:面向对象,人类认知世界的方式:生活中每天都 ...
- [转]深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)
以下内容转自: 作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-l ...
- java方法的多态性理解
1.什么是java的多态 浏览了别人博客中的一些介绍多态的文章,发现大家的描述有点不一样,主要区别在于是否把方法的重写算做多态.一种我比较认同的说法如下: 多态分为两种 a. 编译时多态:方法的重载: ...
- java 重写你可以这么理解 因为 方法名和参数类型个数相同 所以这就是重写了 然后 因为是重写 所以 返回值必须相同
java 重写你可以这么理解 因为 方法名和参数类型个数相同 所以这就是重写了 然后 因为是重写 所以 返回值必须相同
- 深入理解java中main方法
理解main方法语法 深入理解main方法: 解释main方法的形式:public static void main(String[] args){} main方法调用者:虚拟机 java虚拟机需要调 ...
- 深入理解java虚拟机(十一) 方法调用-解析调用与分派调用
方法调用过程是指确定被调用方法的版本(即调用哪一个方法),并不包括方法执行过程.我们知道,Class 文件的编译过程中并不包括传统编译中的连接步骤,一切方法调用在 Class 文件调用里面存储的都只是 ...
随机推荐
- python中动态创建类
class Foo(Bar): pass Foo中有__metaclass__这个属性吗?如果是,Python会在内存中通过__metaclass__创建一个名字为Foo的类对象(我说的是类对象,请紧 ...
- centos7中python3.6报错ModuleNotFoundError: No module named '_ssl' 或者 Max retries exceeded with url: / (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.",))
如果在运行爬虫时报此错:requests.exceptions.SSLError: HTTPSConnectionPool(host='www.baidu.com', port=443): Max r ...
- 网页解析 -- bs4 和 xpath 的简单使用
bs4 BeautifulSoup 是一个可以从HTML或XML文件中提取数据的Python库,它的使用方式相对于正则来说更加的简单方便 中文文档:https://beautifulsoup.read ...
- Python序列类型方法
列表的常用方法 append.insert.extend.pop.remove 元组的两个方法count.index 字符串的常用方法及转义count.find.index.replace.split ...
- mysql使用命令
1.创建用户 create user 'name'@'host' identified by 'psssword'; 2.授权 grant select, updata,insert (all) on ...
- Ubuntu 18.04安装 pyenv、pyenv-virtualenv、virtualenv、Numpy、SciPy、Pillow、Matplotlib
1.目前Python版本管理工具有很多,pyenv是比较好用的一款,安装如下: 输入: git clone https://github.com/pyenv/pyenv.git ~/.pyenv ec ...
- equals和==的应用场景
今天我知道了 抽象类主要作为多个类的模板,接口则定义了多个类应该遵守的规范. "=="比"equals"运行速度快,因为"=="只是比较引用 ...
- 汇编和C/C++的混合编程方式
常用的有三种方式: 在C/C++代码中嵌入汇编指令 汇编调用C/C++ C/C++中调用汇编 实例一: 在C中嵌入汇编: void string_copy(char *dst,const char * ...
- SpringBoot application.properties配置参数详情
multipart multipart.enabled 开启上传支持(默认:true) multipart.file-size-threshold: 大于该值的文件会被写到磁盘上 multipart. ...
- golang 服务端和客户端(二)
1.golang服务端 package main import( "net/http" ) func main(){ //注册处理函数,用户连接,自动调用指定的处理函数 http. ...