Java中的动态转换

Java中的动态转换,java,dynamic,generics,casting,Java,Dynamic,Generics,Casting,在我因为没有做作业而被责骂之前,我一直无法找到关于Java泛型和动态转换的大量问题的任何线索 类型标量定义如下: public class Scalar <T extends Number> { public final String name; T value; ... public T getValue() { return value; } public void setValue(T val) { this.value =

在我因为没有做作业而被责骂之前,我一直无法找到关于Java泛型和动态转换的大量问题的任何线索

类型标量定义如下:

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

}
当然,这通常是不鼓励的。我想要这样一个方法的原因是因为我有一个标量集合,我希望以后更改这些标量的值。但是,一旦它们进入集合,它们的泛型类型参数就不再可访问。所以,即使我想让赋值在运行时完全有效,也无法知道它在编译时是有效的,不管有没有泛型

Map<String, Scalar<? extends Number>> scalars = ...;

Scalar<? extends Number> scalar = scalars.get("someId");

// None of this can work
scalar.value = ...
scalar.setValue(...)
以及捕获ClassCastException?

您有:

this.value.getClass().isAssignableFrom(val.getClass())
这可能会成为一个问题,除非您可以确定
永远不会为空

你还有:

this.value = (T) val;
这将只转换为
Number
而不转换为
T
,因为由于类型擦除,引擎盖下的
T
只是一个
Number
。因此,如果
双精度
val
整数
,则不会引发异常

如果确实要执行选中的强制转换,则必须具有正确的
对象。这意味着您应该在对象的构造函数中传递
Class
。(除非您可以确保
从不为空,在这种情况下,您可以使用您的第一个想法。)拥有该对象(存储在字段中)后,您可以执行选中的强制转换:

T value = valueClass.cast(val);

也许你可以完全忽略泛型?为什么不直接使用数字而不是T?在我沮丧的时候,我很想这样做,但我想离开这个设施,比如说,一个具有单位意识的RichScalar。谢谢你的回复!我可以很容易地检查空值。但是假设我使用了我的第一个解决方案,我将从那里得到什么呢?“我的原始代码段中的强制转换语法引发编译错误,而使用(T)val强制转换仍有未检查的转换警告,这意味着未真正使用isAssignable(…)测试。@dgorur,未指定原始代码段的强制转换。”。这里只有“//一些演员代码”。它应该是:
value=value.getClass().cast(val),它确实可以编译。我将强制转换代码放在代码段的底部,以及它不能为我编译的原因。有趣的是,它确实为您编译了!可能是javac版本还是什么?Eclipse告诉我:类型不匹配:无法从捕获转换#1-of?将数字扩展到T。这就是我在代码片段中提供的原因…CastAway.java:16:找到的不兼容类型:capture#556 of?扩展java.lang.Number所需:T value=value.getClass().cast(val);^1错误$javac-版本javac1.6.0\u 20
this.value.getClass().isAssignableFrom(val.getClass())
this.value = (T) val;
T value = valueClass.cast(val);