简体   繁体   English

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

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

I'm setting up an event system, and I want all my events to extend the Event class I've created.我正在设置一个事件系统,我希望我的所有事件都能扩展我创建的Event class。 However, I also want to at any point be able to add in an additional setCanceled and isCanceled methods.但是,我还希望能够随时添加额外的setCanceledisCanceled方法。 Here's an example:这是一个例子:

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 {...}

As you can see, I used an interface to add in the methods later.如您所见,我使用了一个接口来添加稍后的方法。 The problem is how I have to store if an event is canceled:问题是如果事件被取消我必须如何存储:

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

Notice since Java only allows static fields, I have to create a map to store which events are canceled.注意,由于 Java 只允许 static 字段,我必须创建一个 map 来存储哪些事件被取消。 This works fine, but after a while, this will take up more and more memory considering events are being called very frequently.这工作正常,但过了一会儿,考虑到事件被非常频繁地调用,这将占用越来越多的 memory。 Is there a way to add in cancelable features without using an interface, and without manually putting the code into every event I want to be able to cancel?有没有一种方法可以在不使用界面的情况下添加可取消的功能,并且无需手动将代码放入我希望能够取消的每个事件中? I can't use an EventCancelable class, since then the PlayerMovementEvent wouldn't be able to extend PlayerEvent and EventCancelable at the same time, since I don't want all PlayerEvent s to be cancelable.我不能使用EventCancelable class,因为那时PlayerMovementEvent将无法同时扩展PlayerEventEventCancelable ,因为我不希望所有PlayerEvent都是可取消的。

Or is Java smart enough to empty the map of extra events no longer used since the map is only used in the interface with this added as the argument?或者 Java 是否足够聪明以清空 map 不再使用的额外事件,因为 map 仅在接口中使用,并将this添加为参数?

You could try to use a WeakHashMap , look for an extended example here .您可以尝试使用WeakHashMap在此处查找扩展示例

But, you should know there are caveats:但是,您应该知道有一些注意事项:

  • you have zero control or knowledge when dead entries will be removed from the Map当死条目将从Map中删除时,您的控制或知识为零

  • this puts additional pressure on the GC , as it needs to do additional work for these types of references ( WeakReference under the hood of WeakHashMap )这给GC带来了额外的压力,因为它需要为这些类型的引用做额外的工作( WeakHashMap下的WeakReference

Default methods are not meant to be used like that.默认方法不应该那样使用。 They should provide implementations of methods which can have sensible defaults implemented using the other public methods of the interface.他们应该提供方法的实现,这些方法可以使用接口的其他公共方法实现合理的默认值。

Try composing classes:尝试编写类:

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

Only a few extra lines, but it makes things much easier to understand.只有几行额外的代码,但它使事情更容易理解。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM