当通用方法返回时什么都不返回'什么'但是无法返回null吗?

时间:2016-12-28 10:55:20

标签: java generics java-8 optional

假设我有一个像这样的库方法(非常简略):

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*/哪些合理的占位符不像Integer0那样完全随机?

[编辑] 我试图避免使用Optional.ofNullable,因为此处使用空表示callable.call()未正常完成。

4 个答案:

答案 0 :(得分:6)

如果您需要一个永远不会使用的泛型参数的类型提示,您可以使用Void,JDK在某些情况下也会这样做,例如将Runnable转换为CompletableFuture<T>时,它会将Void用于T。

如果您使用Optional.ofNullable,那么您只需返回null for what2,这是Void的唯一有效值。

  

[edit]我试图避免使用Optional.ofNullable,因为这里使用空来表示callable.call()没有正常完成。

然后你正在使用错误的工具来完成工作。 CompletionStageCompletableFuture具有正确的语义。

答案 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
}