Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.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_Arrays_Generics - Fatal编程技术网

Java泛型和数组构造

Java泛型和数组构造,java,arrays,generics,Java,Arrays,Generics,假设我有一个泛型类和一个泛型参数T,它是一个数字子类。我想在类构造期间初始化一个T数组。可能吗?如果是,怎么做?如果不是,为什么 public class AClass<T extends Number>{ private T array[]; private int arrayOfInt[]; public AClass(int size){ arrayOfInt = new int[size]; array = ? //

假设我有一个泛型类和一个泛型参数T,它是一个数字子类。我想在类构造期间初始化一个T数组。可能吗?如果是,怎么做?如果不是,为什么

public class AClass<T extends Number>{

    private T array[];
    private int arrayOfInt[];

    public AClass(int size){
        arrayOfInt = new int[size];
        array = ? //what should I put here?
    } 
} 
公共类AClass{
专用T数组[];
private int arrayOfInt[];
公共AClass(整数大小){
arrayOfInt=新整数[大小];
array=?//我应该在这里放什么?
} 
} 
这是不可能的


由于Java泛型使用,运行时不知道
T
的类型,因此无法创建它的数组。

T只能在编译时知道。它在运行时是未知的,因此不能初始化数组的内容。但是,您可以创建数组,每个值都将
null

array = (T[]) new Number[size];
编辑:创建任何类型的实例的问题是,您需要知道您想要的默认值是什么,以及您想要调用哪个构造函数。e、 g.没有
new Double()


如下所述,
double[]
将比
Number[]
更高效、更快,除非您需要大的
long
值,否则它将能够存储所有可能的值。

除上述选项外,还可以使用或:

公共类AClass{
专用T数组[];
公共AClass(最终整数大小,T[]a){
数组=(新的ArrayList(){{
对于(int i=0;i

另外,使用反射的解决方案与Langer的泛型常见问题解答(
Utilities.createBuffer
)中建议的解决方案非常接近:

如果要使用数组,有两个选项:

  • Peter Lawrey的答案是,
    array=(T[])新数字[size]。您必须确保永远不要将此变量返回或传递给类之外的代码,这些代码期望它是特定类型的数组,这将导致异常

  • array
    声明为type
    Number[]
    ,然后只需执行
    array=newnumber[size]。这样做的缺点是,当你从中得到任何东西时,你需要显式地转换到
    T
    ,这样才能使用它

  • 这两个在类型擦除后是相同的,它们都会导致未经检查的强制类型转换警告,因此这实际上是个人偏好的问题。前者更方便,而后者更正式(你不是在假装它不是一种类型)


    或者,有些人会告诉您使用
    ArrayList
    。但在内部,ArrayList仍然是使用这两个选项之一实现的。

    是否有办法克服这一限制?@0verbose Yes,reflection。你需要传入一个类型为T的数组才能这样做。@Paulo:是的,没错。Yo将从数组中提取class对象,因此您也可以请求class对象。如果这样做,在使用数字[size]初始化数组之后,我可以执行array[1]=new Double()吗?(假设T当然是双倍的)。这将给你一个ClassCastException。在传递与T(不是子类)相同类型的对象后,需要使用反射来初始化数组@Ryan Amos:如果没有传递到类外的代码中,则不需要。在班里,T是erased@0verbose您已被标记,但标记不正确。只要输入这个,你就会得到通知。@Peter Lawrey:哦,是的。我懂了。A此外,A是“d”而不是“b”。)你到底为什么要那样做?你可以看看ArrayList的解决方案并实现它。@RyanAmos我不懂抱歉-你能详细说明一下吗?这是ArrayList的源代码。与其分配新内存并创建一个不相关的对象来完成任务,只需使用对象中的代码来解决您的问题:gnat-是的,我可以。这就是为什么我没有做-1。@gnat:你真的尝试过你的解决方案吗?您的代码创建的是长度为0的数组,而不是长度为
    size
    +1的数组:谢谢您的解释。我目前计划使用Vector或ArrayList。为了完整起见:ArrayList(在Sun/OpenJDK版本中)使用第二个选项实现,使用
    Object[]data
    public class AClass<T extends Number>{
        private T array[];
    
        public AClass(final int size, T[] a){
            array = (new ArrayList<T>() {{
                for (int i = 0; i < size; i++) {
                    add(null);
                }
            }}).toArray(a);
        }
    
        public AClass(int size, Class<T[ ]> clazz) {  
            array = clazz.cast(java.lang.reflect.Array.newInstance(
                clazz.getComponentType( ), size));  
        }  
    
        public static void main(String[] args) {
            System.out.println("toArray: "
                    + new AClass<Double>(42, new Double[]{}).array.length);
            System.out.println("java.lang.reflect.Array: "
                    + new AClass<Double>(42, Double[].class).array.length);
        }
    }