是否有非静态字段的 Java 接口替代方案?
Is there a Java interface alternative with non-static fields?
我正在设置一个事件系统,我希望我的所有事件都能扩展我创建的 Event
class。但是,我还希望能够随时添加额外的 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 只允许静态字段,我必须创建一个映射来存储哪些事件被取消。这工作正常,但过了一段时间,考虑到事件被非常频繁地调用,这将占用越来越多的内存。有没有一种方法可以在不使用界面的情况下添加可取消的功能,并且无需手动将代码放入我希望能够取消的每个事件中?我不能使用 EventCancelable
class,因为那时 PlayerMovementEvent
将无法同时扩展 PlayerEvent
和 EventCancelable
,因为我不希望所有 PlayerEvent
都可以取消。
或者 Java 是否足够聪明以清空不再使用的额外事件的映射,因为该映射仅在添加了 this
作为参数的界面中使用?
您可以尝试使用 WeakHashMap
,寻找扩展的 。
但是,你应该知道有一些注意事项:
当死条目将从 Map
中删除时,您的控制或知识为零
这给 GC
带来了额外的压力,因为它需要为这些类型的引用做额外的工作(WeakReference
在 WeakHashMap
的幕后)
默认方法不应该那样使用。他们应该提供方法的实现,这些方法可以使用接口的其他 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(); }
...
}
只有几行,但它使事情更容易理解。
我正在设置一个事件系统,我希望我的所有事件都能扩展我创建的 Event
class。但是,我还希望能够随时添加额外的 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 只允许静态字段,我必须创建一个映射来存储哪些事件被取消。这工作正常,但过了一段时间,考虑到事件被非常频繁地调用,这将占用越来越多的内存。有没有一种方法可以在不使用界面的情况下添加可取消的功能,并且无需手动将代码放入我希望能够取消的每个事件中?我不能使用 EventCancelable
class,因为那时 PlayerMovementEvent
将无法同时扩展 PlayerEvent
和 EventCancelable
,因为我不希望所有 PlayerEvent
都可以取消。
或者 Java 是否足够聪明以清空不再使用的额外事件的映射,因为该映射仅在添加了 this
作为参数的界面中使用?
您可以尝试使用 WeakHashMap
,寻找扩展的
但是,你应该知道有一些注意事项:
当死条目将从
中删除时,您的控制或知识为零Map
这给
GC
带来了额外的压力,因为它需要为这些类型的引用做额外的工作(WeakReference
在WeakHashMap
的幕后)
默认方法不应该那样使用。他们应该提供方法的实现,这些方法可以使用接口的其他 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(); }
...
}
只有几行,但它使事情更容易理解。