理解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 文件调用里面存储的都只是 ...
随机推荐
- 将select 转为json
CREATE PROCEDURE[dbo].[WXSP_SerializeJSON](@ParameterSQL AS VARCHAR(MAX))ASBEGIN DECLARE @SQL NVARCH ...
- ssh 使用指定网卡 连接特定网络
有时候,当电脑有两个网卡时:一个网卡 连接免费网络,一个网卡连接收费网络.这样当你想使用免费网络与远程服务器建立连接,使用诸如scp命令或者 ssh 隧道之类传输大文件.这时候你需要指定特定的特定的网 ...
- 使用ML.NET进行自定义机器学习
ML.NET是Microsoft最近发布的用于机器学习的开源,跨平台,代码优先的框架.尽管对我们来说是一个新的框架,但该框架的根源是Microsoft Research,并且在过去十年中已被许多内部团 ...
- python批量执行脚本,使用unittest.TestSuit(); unittest.TextTestRunner().run(); addTest();unittest.defaultTestLoader.discover();
#alltest.py中内容如下import unittest,osdef all(): #path="D:\\study\\python_api_test\\test1203" ...
- SpringCloud学习笔记(十、SpringCloud Sleuth)
目录: 什么是SpringCloud Sleuth 为什么使用SpringCloud Sleuth 如何使用SpringCloud Sleuth 什么是SpringCloud Sleuth: Spri ...
- Pwnable-blackjack
游戏源码 http://cboard.cprogramming.com/c-programming/114023-simple-blackjack-program.html 打开之后是一个游戏 你有5 ...
- day75_10_22频率认证和jwt
一.频率认证原理. 1.从dispatch中获取配置,找到setting中的配置. 2.从thtoyyling中寻找到各个认证类. 3.所有认证类都继承自basethrottle,basethrott ...
- C++ trais技术 模板特化的应用
// traits 的应用 /////////////////////////////////////////// // traits template <typename T> clas ...
- angular 使用ng-zorro的from组件 运行报错
emplate parse errors: Can't bind to 'formGroup' since it isn't a known property of 'form'. 原因:没有导入表单 ...
- NOIP模拟赛1(one)
题目描述 Description 很久以前,有一个序列,序列里填了一些非负整数. \(zzq\) 每次可以选择序列的一个前缀,把这个前缀里的数都-1,如果这个前缀 中有 0 操作就无法进行. \(zz ...