在实际开发中,我们往往需要对某些方法进行增强,常用的方法增强的方式有三种。

  • 类继承 、方法覆盖

    必须控制对象创建,才能使用该方式

  • 装饰者模式方法加强

    必须和目标对象实现相同接口或继续相同父类,特殊构造器(传入被包装对象)

  • 动态代理

我们来编写一个案例感受一下,新建一个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方法增强的更多相关文章

  1. 深入理解 Java 方法

    方法(有的人喜欢叫函数)是一段可重用的代码段.

  2. Java中增强一个类的几种方法

    今天有人问我怎么增强一个类的功能.博客刚好没东西,今天就讲讲增强类. 增强的手段有三种类型: 1.继承或者实现接口:特点是被增强对象不能变,增强的内容不能变. 2.装饰着模式:特点是被增强对象可变,但 ...

  3. 深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)

    作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-language- ...

  4. 理解JAVA - 面向对象(object) - 属性,方法

    理解JAVA - 面向对象(object) - 属性,方法 多态的体现:    向上造型,父类接收子类对象:向上造型:    从父类角度看不到子类独有的方法:面向对象,人类认知世界的方式:生活中每天都 ...

  5. [转]深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)

    以下内容转自: 作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-l ...

  6. java方法的多态性理解

    1.什么是java的多态 浏览了别人博客中的一些介绍多态的文章,发现大家的描述有点不一样,主要区别在于是否把方法的重写算做多态.一种我比较认同的说法如下: 多态分为两种 a. 编译时多态:方法的重载: ...

  7. java 重写你可以这么理解 因为 方法名和参数类型个数相同 所以这就是重写了 然后 因为是重写 所以 返回值必须相同

    java  重写你可以这么理解    因为   方法名和参数类型个数相同  所以这就是重写了    然后  因为是重写  所以  返回值必须相同

  8. 深入理解java中main方法

    理解main方法语法 深入理解main方法: 解释main方法的形式:public static void main(String[] args){} main方法调用者:虚拟机 java虚拟机需要调 ...

  9. 深入理解java虚拟机(十一) 方法调用-解析调用与分派调用

    方法调用过程是指确定被调用方法的版本(即调用哪一个方法),并不包括方法执行过程.我们知道,Class 文件的编译过程中并不包括传统编译中的连接步骤,一切方法调用在 Class 文件调用里面存储的都只是 ...

随机推荐

  1. 记录Flex布局的属性

    容器属性 flex-dirextion(主轴的方向):>>row(水平) | row-reverse(水平取反) | column(垂直) | column-reverse(垂直取反) f ...

  2. Ubuntu 镜像制作 官方教程

    rufus工具下载:下载链接 官方教程:官方教程链接 软件界面预览: 资源来源自网络,如果对您有帮助,请点击推荐~. 我尝试了这个方法可以用.电脑重启时,选择从U盘启动,就能安装系统. 参考链接: h ...

  3. Linux system v 共享内存

    system v 共享内存 #include <sys/types.h> #include <sys/shm.h> int shmget(key_t key, size_t s ...

  4. Linux MySQL 开启远程访问

    进入mysql以后 use mysql; GRANT ALL ON *.* TO user@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;

  5. 2019 Multi-University Training Contest 1 E Path(最短路+最小割)

    题意 链接:https://vjudge.net/problem/HDU-6582 给定一个有向图,可以有重边,每条边上有一个权值表示删掉这条边的代价,问最少花费多少代价能使从s到t节点的最短路径增大 ...

  6. CountDownLatch/CyclicBarrier/Semaphore 使用过吗?

    CountDownLatch/CyclicBarrier/Semaphore 使用过吗?下面详细介绍用法: 一,(等待多线程完成的)CountDownLatch  背景; countDownLatch ...

  7. 手动O3

    #pragma GCC optimize(3,"Ofast","inline") 貌似这玩意并不能在noip考场上用

  8. Html学习之三(列表)

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  9. 题解:openjudge 1.11——01

    题目 思路:二分查找 来,上代码 #include<cstdio> #include<iostream> using namespace std; +]; int n,m; i ...

  10. JAVA的addAll方法

    List和collections工具类都有这个方法!