是否有非静态字段的 Java 接口替代方案?

Is there a Java interface alternative with non-static fields?

我正在设置一个事件系统,我希望我的所有事件都能扩展我创建的 Event class。但是,我还希望能够随时添加额外的 setCanceledisCanceled 方法。 这是一个例子:

public class Event {}
public interface EventCancelable {
    public default void setCanceled(boolean canceled) {...}
    public default boolean isCanceled() {...}
}

public class PlayerEvent extends Event {
    public Player player;
    public PlayerEvent(Player player) {
        this.player = player;
    }
}

public class PlayerMovementEvent extends PlayerEvent implements EventCancelable {...}

如您所见,我使用了一个接口来添加后面的方法。 问题是如果事件被取消我必须如何存储:

public interface EventCancelable {
    Map<Object, Boolean> canceled = new HashMap<>();
    public void setCanceled(boolean canceled) {
        canceled.put(this, canceled);
    }
    public boolean isCanceled() {
        return canceled.get(this);
    }
}

注意,由于 Java 只允许静态字段,我必须创建一个映射来存储哪些事件被取消。这工作正常,但过了一段时间,考虑到事件被非常频繁地调用,这将占用越来越多的内存。有没有一种方法可以在不使用界面的情况下添加可取消的功能,并且无需手动将代码放入我希望能够取消的每个事件中?我不能使用 EventCancelable class,因为那时 PlayerMovementEvent 将无法同时扩展 PlayerEventEventCancelable,因为我不希望所有 PlayerEvent 都可以取消。

或者 Java 是否足够聪明以清空不再使用的额外事件的映射,因为该映射仅在添加了 this 作为参数的界面中使用?

您可以尝试使用 WeakHashMap,寻找扩展的

但是,你应该知道有一些注意事项:

  • 当死条目将从 Map

    中删除时,您的控制或知识为零
  • 这给 GC 带来了额外的压力,因为它需要为这些类型的引用做额外的工作(WeakReferenceWeakHashMap 的幕后)

默认方法不应该那样使用。他们应该提供方法的实现,这些方法可以使用接口的其他 public 方法实现合理的默认值。

尝试作曲 类:

interface Cancellable {
  void cancel();
  boolean isCancelled();
}
class CancellableImpl implements Cancellable {
  private boolean cancelled;
  ...
}

class PlayerMovementEvent extends PlayerEvent implements Cancellable {
  private CancellableImpl cancellable = new Cancellable();
  
  public cancel() { cancellable.cancel(); }
  public isCancelled() { return cancellable.isCancelled(); }
  ...
}

只有几行,但它使事情更容易理解。