浅谈增强一个Java类中的某个方法的几种方式

本文探讨了三种增强Java类中方法的常见方式:一是通过继承,但这种方式要求能控制类的构造;二是使用装饰者模式,需要包装对象和被包装对象实现相同接口,可能导致额外的方法调用;三是利用Java动态代理,要求被增强的对象实现接口,通过InvocationHandler实现方法拦截和增强。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

方式一:继承的方式

采用方式一的前提是能够控制这个类的构造的时候,才可以使用继承
public class Father {
public void run(){
System.out.println(“慢慢走”);
}
}
class Sun extends Father{
public void run(){
System.out.println(“飞”);
}
}

使用装饰者的方式完成类的方法的增强

采用这个方式的时候,需要包装对象和被包装的对象都实现相同的接口,而且包装对象还要获取被包装对象的引用(一般构造方法中传入一个被包装对象).
缺点是:如果接口中的方法比较多,增强其中某个方法,其他的方法也需要原有的调用.
interface Animal{
public void sleep();
public void eat();
}

class Dog implements Animal{
@Override
public void sleep() {

}
@Override
public void eat() {
    System.out.println("吃肉");
}

}

class BigDog implements Animal{
private Dog dog;
public BigDog(Dog dog) {
this.dog = dog;
}
@Override
public void sleep() {
dog.sleep();
}
@Override
public void eat() {
dog.eat();
System.out.println(“喝汤”);
}
}

动态代理的方式

被增强的对象实现接口即可
第一个例子
class Demo {
public void demo(){
Teacher t = new Teacher();
Teacher tt = (Teacher) Proxy.newProxyInstance(Teacher.class.getClassLoader(), Teacher.class.getInterfaces(), new MyInvocationHandler(t));
}

}
class Teacher {
public void teach(){
System.out.println(“普通教学”);
}
public void say(){
System.out.println(“说外语”);
}
}

class MyInvocationHandler implements InvocationHandler{
private Teacher t;
public MyInvocationHandler(Teacher t){
this.t = t;
}
@Override
//所有执行的方法都要进入invoke
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
String name = method.getName();
if (“teach”.equalsIgnoreCase(name)) {
System.out.println(“资深教学”);
//这个return null表示就是只执行上句,不执行被代理对象的方法
return null;
}
//这个表示非指定方法,就不增强
return method.invoke(t, args);
}
}
第二个例子
public class ProxyDemo1 {

@Test
public void demo1(){
    Waiter waiter = new Waitress();
    // waiter.server();

    // 使用动态代理:Proxy.newProxyInstance();
    /**
     * ClassLoader :类加载器.
     * Class[]     :被增强的对象实现的所有接口
     * InvocationHandler    :处理类.
     */
    // 第一个参数:
    ClassLoader classLoader = waiter.getClass().getClassLoader();
    // 第二个参数:
    Class[] interfaces = waiter.getClass().getInterfaces();
    // 第三次参数:

    Waiter waiter2 = (Waiter)Proxy.newProxyInstance(classLoader, interfaces, new MyInvocationHandler(waiter));
    waiter2.server();
    // 说明现在调用代理对象的任何方法的时候,InvocationHandler中的invoke都会执行.
    String s = waiter2.sayHello("张凤");
    System.out.println(s);
}

}

class MyInvocationHandler implements InvocationHandler{

private Waiter waiter;

public MyInvocationHandler(Waiter waiter){
    this.waiter = waiter;
}

@Override
/**
 * 方法的参数:
 * * proxy  :产生的代理对象.
 * * method :当前正在调用的目标类的方法.
 * * params :正在执行的方法中的参数.
 */
public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
    // System.out.println("InvocationHandler invoke 执行了...");
    // System.out.println("微笑=========");
    // waiter.sayHello("张凤");
    // System.out.println(method.getName());
    if("server".equals(method.getName())){
        System.out.println("微笑==========");
        Object obj = method.invoke(waiter, params);
        System.out.println("白白==========");
        return obj;
    }else{
        return method.invoke(waiter, params);
    }


}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值