Java 使用空检查还是首选空方法? 脚本
我想提供一种在我的工作类中选择性地添加回调的可能性。此类回调的接口可能如下所示:Java 使用空检查还是首选空方法? 脚本,java,performance,coding-style,Java,Performance,Coding Style,我想提供一种在我的工作类中选择性地添加回调的可能性。此类回调的接口可能如下所示: public interface Callback<T> { void callback(final T data); } 主意 因此,我想知道使用无操作回调是否是一个好主意,它看起来像这样: @SuppressWarnings("rawtypes") public class NopCallback implements Callback { public static fin
public interface Callback<T> {
void callback(final T data);
}
主意
因此,我想知道使用无操作回调是否是一个好主意,它看起来像这样:
@SuppressWarnings("rawtypes")
public class NopCallback implements Callback {
public static final NopCallback CALLBACK = new NopCallback();
@Override
public void callback(final Object data) {
// do nothing
}
}
默认情况下,工作进程将其回调设置为此NopCallback:
@SuppressWarnings("unchecked")
public Worker() {
callback = NopCallback.CALLBACK;
}
实际问题
我已经发现Nop变体的性能似乎更好(通过调用doWork(…)
1000次,并测量每个变体的持续时间)。我不完全满意的是需要@SuppressWarnings
。我知道我可以摆脱它们,但是我需要在我的每个工作类中都有一个自己的NopCallback实例
长话短说,在干净的代码、可读性、性能等方面,使用这种无操作回调是一个好主意吗?还是有其他(优雅的)替代方案?在我看来相当优雅。它与
Collections.emptyList()
基本相同,它总是返回相同的、空的、不可变的列表。虽然我不会将其设置为公共类,但会使用工厂方法来获取它,以确保警告仅出现在单个位置,并且代码的其余部分是类型安全的:
@SuppressWarnings("unchecked")
private static final Callback NOP = new Callback() {
@Override
public void callback(final Object data) {
// do nothing
}
};
@SuppressWarnings("unchecked")
public static final <T> Callback<T> nop() {
return (Callback<T>) NOP;
}
@SuppressWarnings(“未选中”)
私有静态最终回调NOP=新回调(){
@凌驾
公共无效回调(最终对象数据){
//无所事事
}
};
@抑制警告(“未选中”)
公共静态最终回调nop(){
返回(回调)NOP;
}
这就是
Collections.emptyList()
的实现方式。在我看来非常优雅。它与Collections.emptyList()
基本相同,它总是返回相同的、空的、不可变的列表。虽然我不会将其设置为公共类,但会使用工厂方法来获取它,以确保警告仅出现在单个位置,并且代码的其余部分是类型安全的:
@SuppressWarnings("unchecked")
private static final Callback NOP = new Callback() {
@Override
public void callback(final Object data) {
// do nothing
}
};
@SuppressWarnings("unchecked")
public static final <T> Callback<T> nop() {
return (Callback<T>) NOP;
}
@SuppressWarnings(“未选中”)
私有静态最终回调NOP=新回调(){
@凌驾
公共无效回调(最终对象数据){
//无所事事
}
};
@抑制警告(“未选中”)
公共静态最终回调nop(){
返回(回调)NOP;
}
这就是
Collections.emptyList()
的实现方式。对于未来的读者,我已经为我非常特殊的用例找到了另一种解决方案。因为所有工作类都有相同的父类(例如Worker
),我可以让这个Worker
实现回调
接口本身:
public abstract class Worker<T> implements Callback<T> {
private Callback<T> callback;
public Worker() {
setCallback(this);
}
public void doWork(final T data) {
callback.callback(data);
doRealWork(data);
}
protected abstract void doRealWork(final T data);
@Override
public void callback(final T data) {
// do nothing
}
public void setCallback(final Callback<T> callback) {
if (callback == null) {
this.callback = this;
// Or throw some exception (depending on your situation)
} else {
this.callback = callback;
}
}
}
公共抽象类工作程序实现回调{
私有回调;
公职人员(){
setCallback(这个);
}
公共无效数据(最终T数据){
回调。回调(数据);
doRealWork(数据);
}
受保护的抽象数据(最终T数据);
@凌驾
公共无效回调(最终T数据){
//无所事事
}
public void setCallback(最终回调){
if(回调==null){
this.callback=this;
//或者抛出一些异常(取决于您的情况)
}否则{
this.callback=回调;
}
}
}
在我的特殊用例中,回调方法存在并且可以在工作者自身中访问也没有问题。对于未来的读者,我为我的特殊用例找到了另一个解决方案。因为所有工作类都有相同的父类(例如
Worker
),我可以让这个Worker
实现回调
接口本身:
public abstract class Worker<T> implements Callback<T> {
private Callback<T> callback;
public Worker() {
setCallback(this);
}
public void doWork(final T data) {
callback.callback(data);
doRealWork(data);
}
protected abstract void doRealWork(final T data);
@Override
public void callback(final T data) {
// do nothing
}
public void setCallback(final Callback<T> callback) {
if (callback == null) {
this.callback = this;
// Or throw some exception (depending on your situation)
} else {
this.callback = callback;
}
}
}
公共抽象类工作程序实现回调{
私有回调;
公职人员(){
setCallback(这个);
}
公共无效数据(最终T数据){
回调。回调(数据);
doRealWork(数据);
}
受保护的抽象数据(最终T数据);
@凌驾
公共无效回调(最终T数据){
//无所事事
}
public void setCallback(最终回调){
if(回调==null){
this.callback=this;
//或者抛出一些异常(取决于您的情况)
}否则{
this.callback=回调;
}
}
}
在我的特殊用例中,回调方法存在并且可以在工作者自身中访问也没有问题。您所描述的是
智能代理委托
,已经有相当多的例子可以做到这一点。总而言之,您会在意吗?如果你每秒只调用这个东西10^6次,那就没什么大不了的了。@MikeDunlavey当然没什么大不了的,因为实际的回调实现和工作程序本身都需要更多的时间。更多的是思考什么是最好的解决方案,我理解。当真正的加速隐藏在视线之外时,这些都是人们关注的焦点。很抱歉重复这一点,但我几乎普遍看到人们在他们的软件很容易有空间进行巨大的加速时,一旦他们有了透视感,他们就会大发雷霆。这就像一个关于醉汉在路灯下寻找钥匙的老笑话,因为灯就在那里。你所描述的是智能代理委托
,已经有很多这样的例子了。从大局来看,你会在意吗?如果你每秒只调用这个东西10^6次,那就没什么大不了的了。@MikeDunlavey当然没什么大不了的,因为实际的回调实现和工作程序本身都需要更多的时间。更多的是思考什么是最好的解决方案,我理解。当真正的加速隐藏在视线之外时,这些都是人们关注的焦点。很抱歉重复这一点,但我几乎普遍看到peo