动态调度、重载和泛型
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++ 的演变时,是向前迈出两步的情况。
使用这个 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++ 的演变时,是向前迈出两步的情况。