动态调度、重载和泛型

Dynamic dispatch, overloading and generics

使用这个 class:

public class Fallible<T> {

    private final Exception exception;
    private final T value;

    public Fallible(final T value) {
        this.value = value;
        this.exception = null;
    }

    public Fallible(final Exception exception) {
        this.value = null;
        this.exception = exception;
    }

}

我可以安全地假设 value 永远不会 包含异常对象吗?

不,你不能做出这样的假设。例如:

Object obj = new Exception();
Fallible f = new Fallible(obj);

将调用通用构造函数。

检查这个的唯一方法是使用 instanceof:

显式检查 value 的类型
public Fallible(final T value) {
  if (value instanceof Exception) {
    this.exception = (Exception) value;
    this.value = null;
  } else {
    this.value = value;
    this.exception = null;
  }
}

不,你不能。

如果您考虑运行时获得的 type-erased 版本,这将更容易分析:

public Fallible(final T value) 变为 public Fallible(final java.lang.Object value).

所以重载 Fallible(final Exception exception) 将在匹配更好的情况下使用;即如果 exception 是类型 Exception 或其子 class。

构建允许从 java.lang.Object 构建但禁止从子 class 构建(在编译时)的 class 在 Java 中是不可能的。您将不得不依赖运行时检查(instanceof 等)。顺便说一下,您可以使用模板在 C++ 中解决这个问题。在这方面以及许多其他方面,Java 当被视为 C++ 的演变时,是向前迈出两步的情况。