Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从泛型类返回数组_Java - Fatal编程技术网

Java 从泛型类返回数组

Java 从泛型类返回数组,java,Java,当我运行这个时,我得到了一个ClassCastException错误,因为当我运行代码时,隐式地将d转换为double。但是,如果我将中对d的引用更改为Object[],则它不能作为set函数的参数。如果我将set函数更改为接受一个对象[],则一切正常,但如果有人在类型不为N的对象上调用set,则该类将在运行时失败 我需要一个可以get()旧数组(或其克隆)和set()数据到新数组的解决方案 public class Foo<N> { public static void

当我运行这个时,我得到了一个
ClassCastException
错误,因为当我运行代码时,隐式地将d转换为double。但是,如果我将中对d的引用更改为
Object[]
,则它不能作为set函数的参数。如果我将set函数更改为接受一个
对象[]
,则一切正常,但如果有人在类型不为
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;
    }

}
公共类Foo{
公共静态void main(字符串[]args){
Foo-Foo=新的Foo();
Double[]d=foo.get();
//做些事情来。。。
foo.set(d);
}
N[]数据;
公共食物({
数据=(N[])新对象[2];
}
公共N[]获取(){
返回(N[])个数据;
}
公共无效集(N[]数据){
这个数据=数据;
}
}

这有个窍门

class Foo<N> {

    // Deliberately no parameters.
    N[] myArray = makeArray();

    private N[] makeArray(N... ns) {
        return ns;
    }

    public N[] get() {
        return myArray;
    }
}
class-Foo{
//没有参数。
N[]myArray=makeArray();
专用N[]生成数组(N…ns){
返回ns;
}
公共N[]获取(){
返回myArray;
}
}

这看起来可能没有强制转换(这是一件好事),但实际上有,它只是由
varargs
系统完成的。

要创建具有正确运行时类型的数组,需要该类型的某种运行时表示。像
Foo
这样的泛型类没有
N
的运行时表示

有两种解决方案:

  • 改用
    列表
    。这是最好的,如果可能的话
  • 手动添加
    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);
    
    public Foo(类newDataClass){
    data=(N[])Array.newInstance(newDataClass,2);
    }
    Foo-Foo=新的Foo(Double.class);
    

    编辑:

    如果您想做的是获取现有
    数组的副本,则可以使用
    (N[])data.clone()
    。设置它不会是一个问题。

    一个方便(但详细)的方法是将构造函数更改为使用数组类型的伪参数,因为您知道它在主方法中是双精度的

      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);
             }
    
      }
    
    公共类Foo{
    N[]数据;
    公共Foo(N inType){
    data=(N[])Array.newInstance(inType.getClass(),2);
    }
    公共N[]获取(){
    返回(N[])个数据;
    }
    公共无效集(N[]数据){
    这个数据=数据;
    }
    公共静态void main(字符串[]args){
    Foo-Foo=新Foo(新双精度(0));
    Double[]d=foo.get();
    //做些事情来。。。
    foo.set(d);
    }
    }
    
    泛型的问题是,它在运行时没有任何特定类型。它只是类
    对象
    ,这意味着创建这样的对象是完全没有意义的,因为实际上,您只需要创建一个类型为
    对象
    的对象


    但是,您可以从类之外创建这样的对象,因为这里知道对象的真实类型(
    Double
    )。因此,我建议使用某种类型的
    列表
    ,它可以是动态的,存储值。

    可能的重复不是q的重复。您可以使用它提取类型和数组。newInstance创建数组可能我不清楚这个问题,但在我的情况下数组已经实例化,我需要对其进行更改。所以我需要从foo那里得到它做点什么。然后重置它。我没有在构造函数中实例化它的解决方案。@在您的示例中,您在
    Foo
    构造函数中创建了数组。这不是它应该如何工作的吗?你能更新这个问题让它更清楚吗?@OldCurmudgeon:这行不通。您将始终在
    myArray
    中获得一个
    对象
    数组。当初始化器调用
    makeArray
    时,没有
    N
    留下的痕迹,它已被擦除。泛型vararg方法始终创建
    对象
    数组。根本不可能创建泛型类型的数组。例如,@Lii-擦除后所有数组都是
    对象[]
    。这个把戏只是避免了施放。好吧,看来我误解了目的,对不起。“擦除后,所有数组都是
    Object[]
    ”我不确定您在这里的意思。在运行时,泛型类型的所有数组都将是
    Object[]
    。但不是其他的,
    Double[]
    Double[]
    将具有这些运行时类型。擦除只涉及泛型类型。