【发布时间】:2010-10-15 02:27:19
【问题描述】:
在我因为没有做功课而受到责备之前,我一直无法找到有关 Java 泛型和动态转换的大量问题的任何线索。
类型Scalar定义如下:
public class Scalar <T extends Number> {
public final String name;
T value;
...
public T getValue() {
return value;
}
public void setValue(T val) {
this.value = val;
}
}
我想要一个看起来像这样的方法:
public void evilSetter(V val) {
this.value = (T) val;
}
当然,这通常是不鼓励的。我想要这种方法的原因是因为我有一个标量集合,我想稍后更改它们的值。但是,一旦它们进入集合,它们的泛型类型参数就不再可访问。因此,即使我想进行一个在运行时完全有效的赋值,也无法知道它在编译时是否有效,不管有没有泛型。
Map<String, Scalar<? extends Number>> scalars = ...;
Scalar<? extends Number> scalar = scalars.get("someId");
// None of this can work
scalar.value = ...
scalar.setValue(...)
那么我该如何实现一个检查型强制转换和设置方法呢?
public <V extends Number> void castAndSet(V val) {
// One possibility
if (this.value.getClass().isAssignableFrom(val.getClass()) {
// Some cast code here
}
// Another
if (this.value.getClass().isInstanceOf(val) {
// Some cast code here
}
// What should the cast line be?
// It can't be:
this.value = this.value.getClass().cast(val);
// Because this.value.getClass() is of type Class<?>, not Class<T>
}
所以我只剩下使用了
this.value = (T) val;
并捕获 ClassCastException?
【问题讨论】:
-
也许您可以完全省略泛型?为什么不直接使用 Number 而不是 T?
-
在我的挫折中,我很想这样做,但我想离开这个设施,例如,一个单位感知的 RichScalar。
标签: java dynamic generics casting