Java 可以用AspectJ替换抽象类吗

Java 可以用AspectJ替换抽象类吗,java,abstract-class,aspectj,Java,Abstract Class,Aspectj,给定java.util.Timer您可以执行以下操作: // where TimerMock extends Timer Timer around(): call (Timer.new()) { return new TimerMock(); } 这是否可能与抽象类有关?以java.util.TimerTask为例,它是一个具有以下签名的抽象类: public abstract class TimerTask implements Runnable { (...) pu

给定
java.util.Timer
您可以执行以下操作:

// where TimerMock extends Timer
Timer around(): call (Timer.new()) {
    return new TimerMock();
}
这是否可能与抽象类有关?以
java.util.TimerTask
为例,它是一个具有以下签名的
抽象类:

public abstract class TimerTask implements Runnable {
    (...)
    public abstract void run();
}
是否可以返回扩展TimerTask的类?


如何匹配?

您将很难正确匹配连接点

让我用你最初的例子来解释这些问题:

public aspect InterceptTimer
{
    // where TimerMock extends Timer
    Timer around(): call(Timer.new())
    {
         return new TimerMock();
    }
}

public class Test {

    public void method() 
    {
        Timer a = new Timer();
        System.out.println(a.toString());
    }
}
在编织之后,AspectJ将替换
计时器a=new Timer()Timer a=new TimerMock()的事物,code>哪个工作正常

然而,对于抽象类,事情并不是那么顺利。在本例中,您希望用具体类替换抽象类的具体实现。这样做的一个方面可能类似于(假设现在TimerMock扩展了TimerTask):

“TimerTask+”
确保您拦截扩展
TimerTask的所有类,并且
“!in(InterceptTimer)”
确保切入点不会拦截连接点
“new TimerMock();”
,这将导致无限递归

现在让我们假设您有一个具体的类:

public class MyTimer extends TimerTask {

    @Override
    public void run() 
    {
       // ...
    }
}  
如果要拦截以下创建:

public void method() {
    MyTimer a = new MyTimer();
    a.run();
} 
您会立即看到错误: " 应用于构造函数调用的不兼容返回类型(void test.MyTimer() "

这是因为连接点“new MyTimer()”在词汇上与“TimerTask”不同。如果您可以通过“new TimerTask()”来更改“new MyTimer()”连接点,那么它将起作用,但是,您不能这样做,因为TimerTask是一个抽象类

如果你想聪明一点,把“建议”改为:
objectaround():call(MyTask+.new())&&!在(截取计时器){…}

您不会得到编译错误,而是运行时错误:

"java.lang.ClassCastException: test.TimerMock cannot be cast to test.MyTimer"
这是因为在编织过程中,AspectJ将执行以下操作:
MyTimer a=(MyTimer)new TimerMock()


我认为不可能做你想做的事情,至少不能用这种方法,也许有一种方法可以利用“执行”和“调用”连接点之间的差异来做到这一点。

Thks了解详细程度!
"java.lang.ClassCastException: test.TimerMock cannot be cast to test.MyTimer"