当泛型方法 returns 'nothing' 但 null 不能 returned 时,return 怎么办?

What to return when generic methods returns 'nothing' but null can't be returned?

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

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();
    }
}

我想要一些没有 return 值的东西,例如:

    Library.</*What1*/>doSomethingWith(() -> {
        foo();
        return /*what2*/;
    });

我对没有 return 值的泛型方法的第一直觉是使类型 Void 和 returning null,但是因为结果是包装在 Optional 中,这会引发异常。

/*What1*//*what2*/ 的合理占位符是什么,它们看起来不像 Integer0 那样完全随机?

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

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

使用 Void

如果你使用 Optional.ofNullable 那么你可以 return null for what2,这是 Void.

的唯一有效值

[edit] I'm trying to avoid Optional.ofNullable because empty is used here to indicate that callable.call() did not complete normally.

那么您使用了错误的工具来完成这项工作。 CompletionStageCompletableFuture 具有正确的语义。

对return类型使用Void,这是"nothing"的合理选择,但实际上return是Void的一个实例。

虽然 javadoc for Void 说是:

...an uninstantiable placeholder class...

你仍然可以实例化它:

try {
    Constructor<Void> c = Void.class.getDeclaredConstructor();
    c.setAccessible(true);
    return c.newInstance();
} catch (Exception perfunctory) {
    return null; // won't happen
}

您也可以创建自己的类型,类似于 Void

public class Result {
     public static final Result OK = new Result();

     private Result(){}
}

然后 return Result.OK.

如果需要,您还可以增强此类型以表示错误。

但如果您不需要任何特殊的东西,也许使用 java Void 更可取。

我通常使用 Boolean.TRUE 来标记成功,但您也可以 return Void.class。两者都很便宜,因为并非每个 return 都会创建一个要丢弃的新对象。虽然 Class<Void> 不仅仅是 Void,但它也可以用于将某些东西标记为 void

如前所述,您也可以创建自己的 Result-class/-enum。

或者您当然也可以 return Optional.<Void>nothing()。这会导致一些 Optional<Optional<Void>>,但也可以解决问题。

如果您认为以上所有内容都很丑陋,我担心 API 可能无法很好地满足您的需求。提出 issue/pull 请求或寻找其他东西。