当我运行此命令时出现ClassCastException
错误,因为在运行代码时将d隐式转换为double。但是,如果我将对d in的引用更改为Object[]
,则它不能成为set函数的参数。如果我将set函数更改为接受Object[]
,那么一切正常,但如果有人对不属于N
类型的对象调用set,则该类将在运行时失败。
我需要一个可以get()
旧数组(或其克隆)并且可以set()
数据到新数组的解决方案。
public class Foo<N> {
public static void main(String[] args) {
Foo<Double> foo = new Foo<Double>();
Double[] d = foo.get();
// do stuff to d ...
foo.set(d);
}
N[] data;
public Foo() {
data = (N[]) new Object[2];
}
public N[] get() {
return (N[]) data;
}
public void set(N[] data) {
this.data = data;
}
}
答案 0 :(得分:1)
这是一个诀窍。
class Foo<N> {
// Deliberately no parameters.
N[] myArray = makeArray();
private N[] makeArray(N... ns) {
return ns;
}
public N[] get() {
return myArray;
}
}
这可能看起来没有强制转换(这是一件好事),但事实上,它只是由varargs
系统完成。
答案 1 :(得分:1)
要使用正确的运行时类型创建数组,需要某种类型的运行时表示。像Foo<N>
这样的泛型类没有N
的运行时表示。
有两种解决方案:
List<N>
。如果可能的话,这是最好的!N
传递给Class<N>
手动添加Foo
的运行时表示,使用java.lang.reflect.Array.newInstance
创建数组。第二个解决方案的代码:
public Foo(Class<N> newDataClass) {
data = (N[]) Array.newInstance(newDataClass, 2);
}
Foo<Double> foo = new Foo<>(Double.class);
修改强>
如果您要执行的操作是获取现有Double
数组的副本,则可以使用(N[]) data.clone()
执行此操作。设置它不会有问题。
答案 2 :(得分:1)
一种方便(但冗长)的方法是更改构造函数以使用数组类型获取伪参数,因为您知道它在main方法中是双精度。
public class Foo<N> {
N[] data;
public Foo(N inType) {
data = (N[]) Array.newInstance(inType.getClass(), 2) ;
}
public N[] get() {
return (N[]) data;
}
public void set(N[] data) {
this.data = data;
}
public static void main(String[] args) {
Foo<Double> foo = new Foo<Double>(new Double(0));
Double[] d = foo.get();
// do stuff to d ...
foo.set(d);
}
}
答案 3 :(得分:0)
泛型的问题是,它在运行时没有任何特定类型。它只是类Object
,这意味着,创建这样的对象是完全没有意义的,因为事实上,你只需要创建一个Object
类型的对象。
但是,您可以从类外部创建此类对象,因为此处已知对象的实际类型(Double
)。因此,我建议使用某种List
(可以是动态的)来存储值。