假设我有一个像这样的库方法(非常简略):
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()
未正常完成。
答案 0 :(得分:6)
如果您需要一个永远不会使用的泛型参数的类型提示,您可以使用Void
,JDK在某些情况下也会这样做,例如将Runnable
转换为CompletableFuture<T>
时,它会将Void用于T。
如果您使用Optional.ofNullable
,那么您只需返回null
for what2,这是Void
的唯一有效值。
[edit]我试图避免使用Optional.ofNullable,因为这里使用空来表示callable.call()没有正常完成。
然后你正在使用错误的工具来完成工作。 CompletionStage
或CompletableFuture
具有正确的语义。
答案 1 :(得分:4)
我通常使用Boolean.TRUE
来标记成功,但您也可以返回Void.class
。两者都很便宜,因为不是每个返回都会创建一个要丢弃的新对象。虽然Class<Void>
不仅仅是Void
,但它也可以用于将某些内容标记为void
。
如前所述,您还可以创建自己的Result-class / -enum。
或者您当然可以返回Optional.<Void>nothing()
。这会产生一些Optional<Optional<Void>>
,但也可以做到这一点。
如果您认为以上所有内容都很难看,我担心API可能不适合您的需求。提出问题/拉取请求或寻找其他东西。
答案 2 :(得分:1)
您还可以创建类似于Void
public class Result {
public static final Result OK = new Result();
private Result(){}
}
然后返回Result.OK
。
如果需要,您还可以增强此类型以表示错误。
但如果您不需要任何特殊内容,可能最好使用java Void
。
答案 3 :(得分:0)
使用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
}