当泛型方法返回'Nothing'时返回什么,但不能返回null?
假设我有这样的(非常略)库方法:当泛型方法返回'Nothing'时返回什么,但不能返回null?
public static <V> Optional<V> doSomethingWith(Callable<V> callable) {
try {
return Optional.of(callable.call());
} catch (Exception ex) {
// Do something with ex
return Optional.empty();
}
}
而且我要的东西,没有返回值,如:
Library.</*What1*/>doSomethingWith(() -> {
foo();
return /*what2*/;
});
我的第一本能通用不返回值的方法是制作Void
类型并返回null
,但是因为结果被封装在Optional
中,这会引发异常。
什么是合理的占位符/*What1*/
和/*what2*/
看起来不像Integer
和0
完全随机?
我试图避免Optional.ofNullable
,因为此处用空表示callable.call()
未正常完成。
我通常使用Boolean.TRUE
来标记成功,但您也可以返回Void.class
。两者都很便宜,因为并不是每一个回报都会产生一个新的物品被丢弃。尽管Class<Void>
不仅仅是Void
它也可以用于标记void
之类的内容。
如前所述,您也可以创建自己的Result-class/-enum。您也可以返回Optional.<Void>nothing()
。这会导致一些Optional<Optional<Void>>
,但也有窍门。
如果您认为上述所有内容都很难看,我担心API可能无法很好地满足您的需求。提出问题/拉请求或寻找其他东西。
我最喜欢枚举选项。特别是因为昨天我只是想知道为什么没有内置(非原始)类型有两种可能性。比较:'Void'有一个可能性:'null','Boolean'有三个:'null','FALSE','TRUE'。 (“对象”当然有无限的可能性。) –
如果您需要一个永远不会使用的泛型参数的类型提示,您可以使用Void
,但在某些情况下,JDK也会这样做。转换成Runnable
时CompletableFuture<T>
它使用作废的T.
如果使用Optional.ofNullable
那么你可以返回null
为what2,这是Void
唯一有效的值。
我试图避免Optional.ofNullable,因为此处使用empty来指示callable.call()没有正常完成。
然后,您使用的工具是错误的工具。 CompletionStage
或CompletableFuture
具有正确的语义。
使用Void
作为返回类型,这是“无”的合理选择,但实际返回Void
的实例。
虽然javadoc for Void
说这是:
...一个不可占位符类...
您仍然可以对其进行实例化:
try {
Constructor<Void> c = Void.class.getDeclaredConstructor();
c.setAccessible(true);
return c.newInstance();
} catch (Exception perfunctory) {
return null; // won't happen
}
不好的建议。当你破解一个'Void'的实例时,你会破坏几个合约,更不用说在将来/备用JDK中导致'不会发生'的可能实现变化发生。 –
@标记哪个合约**,特别是**,被打破?请提供链接等。我坚持认为没有这样的合同,如果将来的版本更改构造函数以使此代码不起作用(非常不可能),那么请担心。 – Bohemian
您还可以创建你的自己类型与Void
public class Result {
public static final Result OK = new Result();
private Result(){}
}
然后返回Result.OK
。
如果需要,还可以增强此类型以表示错误。
但也许使用java Void
是最好的,如果你不需要任何特殊的。
我会为此使用枚举。 – TheConstructor
这取决于你必须做什么,单身人士你不能管理错误,因为有了它,你将需要一个不同的实例,每次有不同的消息。 – rascio
枚举继承了一些更多的方法(比如'toString'),为什么我通常更喜欢它们用于像所提出的'Result.OK'这样的信号实例。如果在API中使用某个'ResultOrError'类而不是'Optional',那么OP的问题就不存在了。 – TheConstructor
你不能改变库方法来使用'Optional.ofNullable'吗?如果它始终存在,那么返回可选项有什么意义? –
库方法非常简短。当条件发生时,它实际上可以返回'Optional.empty()'。 –
您可以添加一个合理命名的本地类并返回该类的一个实例 – glee8e