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

ds97pgxw  于 2021-06-27  发布在  Java
关注(0)|答案(2)|浏览(309)

我正在建立一个事件系统,我希望我所有的事件都能扩展 Event 我创建的类。不过,我也希望在任何时候都能添加一个额外的 setCanceled 以及 isCanceled 方法。举个例子:

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只允许静态字段,所以我必须创建一个Map来存储取消的事件。这工作得很好,但是过一段时间,考虑到事件被频繁调用,这将占用越来越多的内存。有没有一种方法可以在不使用接口的情况下添加可取消的特性,也不必手动将代码放入每个我想取消的事件中?我不能用枪 EventCancelable 同学们,从那以后 PlayerMovementEvent 无法扩展 PlayerEvent 以及 EventCancelable 同时,因为我不想要所有的 PlayerEvent 是可以取消的。
或者java是否足够聪明,可以清空不再使用的额外事件的Map,因为Map只在与的接口中使用 this 添加为参数?

ztyzrc3y

ztyzrc3y1#

默认方法不应该这样使用。它们应该提供方法的实现,这些方法可以使用接口的其他公共方法实现合理的默认值。
尝试组合类:

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(); }
  ...
}

只是多了几行,但这使事情更容易理解。

qvk1mo1f

qvk1mo1f2#

你可以试着用 WeakHashMap ,请在此处查找扩展示例。
但是,你应该知道有一些注意事项:
您无法控制或知道何时从数据库中删除死条目 Map 这会对发动机施加额外的压力 GC ,因为它需要为这些类型的引用做额外的工作( WeakReference 在…的罩下 WeakHashMap )

相关问题