Returning an Array from a generic class

I get a ClassCastException error when I run this because of the implicit cast of d to a double when I run the code. However, if I change reference to d in to Object[] then it can't be a parameter to the set function. If I change the set function to accept an Object[] then everything works fine, but then the class will fail at runtime if anyone calls set on an object that isn't of type N .

I need a solution that can get() the old array (or a clone thereof) and that can set() data to a new array.

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

}

To create an array with the right runtime type requires some kind of runtime representation of that type. A generic class like Foo<N> has no runtime representation of N .

There are two solutions:

  • Use a List<N> instead. This is best if it is possible!
  • Manually add a runtime representation of N by passing in a Class<N> to Foo , use java.lang.reflect.Array.newInstance to create the array.
  • Code for the second solution:

    public Foo(Class<N> newDataClass) {
        data = (N[]) Array.newInstance(newDataClass, 2);
    }
    
    Foo<Double> foo = new Foo<>(Double.class);
    

    EDIT:

    If what you want to do is instead to get a copy of an existing Double array you can do that with (N[]) data.clone() . Setting it will not be a problem.


    There's a trick to this.

    class Foo<N> {
    
        // Deliberately no parameters.
        N[] myArray = makeArray();
    
        private N[] makeArray(N... ns) {
            return ns;
        }
    
        public N[] get() {
            return myArray;
        }
    }
    

    This may look like there is no casting (which is a good thing) but actually there is, it is just being done by the varargs system.


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

      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);
             }
    
      }
    
    链接地址: http://www.djcxy.com/p/31254.html

    上一篇: 点击重新启动关键帧

    下一篇: 从泛型类中返回一个数组