Java中是否有某种类型的@annotation或其他方法来强制方法扩展,而不是覆盖?
具体来说,假设我有一个类 Foo:
class Foo {
public void bar(Thing thing) {
// ...
}
}
有没有一种方法可以在编译时强制任何扩展 Foo 并且还覆盖 bar 的类 X 调用super.bar(thing)
first?
Java中是否有某种类型的@annotation或其他方法来强制方法扩展,而不是覆盖?
具体来说,假设我有一个类 Foo:
class Foo {
public void bar(Thing thing) {
// ...
}
}
有没有一种方法可以在编译时强制任何扩展 Foo 并且还覆盖 bar 的类 X 调用super.bar(thing)
first?
不,你必须明确地写出来。
构造函数的旁注:实例化子类时将隐式调用超类的空构造函数,无论后者的构造函数有多少参数。
通常,您可以做的是创建一个final
调用可扩展方法的方法。
class Foo {
@Override
public final void bar(Thing thing) {
// super code comes here
this.doBar(thing);
}
public abstract void doBar(Thing thing);
}
你打电话时
foo.bar(thing);
您的超级代码首先运行,然后是子类中的代码。
通过这种方式,您可以保护您的全部bar
逻辑,并且只允许扩展/重新实现某些部分。
此外,它还允许您对结果进行后处理,或将代码分解为某些子任务。
您可以声明bar
为final
,然后从 调用抽象方法bar
,这将强制子类实现“扩展”。
abstract class Foo {
public final void bar(Thing thing) {
barImpl(thing);
overrideMe(thing);
}
private final void barImpl(Thing thing) {
// Original implementation of "bar" here.
}
protected abstract void overrideMe(Thing thing);
}
编辑
我已从 更改overrideMe
为public
,protected
因此用户Foo
不能只调用overrideMe
而不是bar
.
虽然您不能强制代码在编译时调用其超类,但在运行时检测代码不调用超类时并不难。
class Foo {
private boolean baseCalled;
public final void bar(Thing thing) {
baseCalled = false;
barImp(thing);
if (!baseCalled) {
throw new RuntimeException("super.barImp() not called");
}
}
protected void barImp(Thing thing) {
baseCalled = true;
. . . // base class implementation of bar
}
}
请注意,这扩展到多个继承级别,无需进一步阐述。该方法特别适用于从内部调用的方法Foo
;在这些情况下,您通常可以放弃final
限定符并重定向到实现方法,而只需定义基类方法来设置标志。清除标志将在每个调用点完成。
上述模式在 Android 框架中被广泛使用。它不保证在子类覆盖中super.barImp
被称为第一件事;只是它被称为。
@AroundInvoke
如果您使用的是 EJB,您可以尝试使用注解。
通过使用反射,您可以在父类中找到相同的方法,并且可以使用与调用原始方法相同的参数来调用它。
请注意,在这种情况下,您必须避免super.bar(thing)
调用,否则它们将被调用两次。