You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AspectJ技术咨询:能否重写父类方法并通过super调用父类原方法?

当然可以!用AspectJ实现类似“重写父类方法+调用super原方法”的效果

完全没问题,AspectJ的Around通知正好能满足你的需求——它允许你拦截目标方法的执行,插入自定义逻辑,并且可以选择是否调用原方法(这就对应你说的super调用父类原方法的场景)。

先把你没写完的子类代码补全,方便演示:

package test;
public class Child extends Parent {
    // 假设子类原本没有重写doSomething方法
}

接下来直接上切面实现代码,一看就懂:

package test;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class ParentMethodInterceptor {
    // 切点定位到Parent类的doSomething方法,包括所有子类调用该方法的场景
    @Around("execution(void test.Parent.doSomething())")
    public void interceptAndOverride(ProceedingJoinPoint joinPoint) throws Throwable {
        // 这里是你自定义的"重写"逻辑,相当于子类重写方法里的自定义代码
        System.out.println("Aspect: 我是新增的前置逻辑,替代/补充父类方法");
        
        // 调用原方法——这一步就等价于在子类重写方法里调用super.doSomething()
        joinPoint.proceed();
        
        // 还可以添加后置逻辑,按需选择
        System.out.println("Aspect: 父类原方法执行完了,我来收尾");
    }
}

运行效果

当你执行Parent类的main方法时,输出会变成:

Aspect: 我是新增的前置逻辑,替代/补充父类方法
Parent is doing something
Aspect: 父类原方法执行完了,我来收尾

关键细节说明

  • 切点表达式精准度:如果只想拦截子类调用父类方法的场景,可以把切点改成execution(void test.Child.doSomething());如果要匹配所有继承Parent的子类,用execution(void test.+.doSomething()) && target(test.Parent)更灵活。
  • 原方法调用的控制:joinPoint.proceed()必须显式调用,否则原父类方法不会执行(相当于完全替换原方法);如果需要传递参数给原方法,可以用proceed(Object[] args)。
  • 织入方式:要确保AspectJ的织入生效,你可以选择编译时织入(CTW)(用AspectJ编译器ajc编译代码)或者加载时织入(LTW)(通过JVM参数配置织入代理)。

如果子类本身已经重写了doSomething,你想在切面里强制调用父类的原方法,这时候可以通过反射实现,但一般不推荐——AspectJ的设计初衷是通过切点拦截来实现横切逻辑,而非直接绕过子类重写。

内容的提问来源于stack exchange,提问作者vesuvius

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:38:41