由于Java泛型的实现,您不可能有这样的代码:

public class GenSet<E> {
    private E a[];

    public GenSet() {
        a = new E[INITIAL_ARRAY_LENGTH]; // error: generic array creation
    }
}

如何在维护类型安全的同时实现这一点?

我在Java论坛上看到了这样一个解决方案:

import java.lang.reflect.Array;

class Stack<T> {
    public Stack(Class<T> clazz, int capacity) {
        array = (T[])Array.newInstance(clazz, capacity);
    }

    private final T[] array;
}

但我真的不明白这是怎么回事.

推荐答案

作为回报,我必须问一个问题:你的GenSet是"判断"还是"未判断"?

  • Checked:strong typing.GenSet清楚地知道它包含什么类型的对象(即,它的构造函数是用Class<E>参数显式调用的,当传递给方法的参数不是E类型时,它们将抛出异常.请参见Collections.checkedCollection.

    -> in that case, you should write:

    public class GenSet<E> {
    
        private E[] a;
    
        public GenSet(Class<E> c, int s) {
            // Use Array native method to create array
            // of a type only known at run time
            @SuppressWarnings("unchecked")
            final E[] a = (E[]) Array.newInstance(c, s);
            this.a = a;
        }
    
        E get(int i) {
            return a[i];
        }
    }
    
  • Unchecked:weak typing.实际上没有对作为参数传递的任何对象执行类型判断.

    -> in that case, you should write

    public class GenSet<E> {
    
        private Object[] a;
    
        public GenSet(int s) {
            a = new Object[s];
        }
    
        E get(int i) {
            @SuppressWarnings("unchecked")
            final E e = (E) a[i];
            return e;
        }
    }
    

    请注意,数组的组件类型应为type参数的erasure:

    public class GenSet<E extends Foo> { // E has an upper bound of Foo
    
        private Foo[] a; // E erases to Foo, so use Foo[]
    
        public GenSet(int s) {
            a = new Foo[s];
        }
    
        ...
    }
    

所有这些都源于Java中泛型的一个已知且故意的弱点:它是使用擦除实现的,因此"泛型"类不知道它们在运行时使用的是什么类型参数,因此除非实现某种显式机制(类型判断),否则无法提供类型安全性.

Java相关问答推荐

Informix PrepareStatement引发错误-将LIMIT Clause添加到查询时,字符到数字的转换过程失败

在Java 11+中,我们可以在不编译多个文件的情况下以某种方式执行吗?

在applitcation.properties中找到的字符串中输入变量

无法从TemporalAccessor获取Instant:{},ISO解析为2024-04- 25 T14:32:42类型为java.time. form.Parsed

如何计算内循环的时间复杂度?

@ EnableRouting注释在Kotlin项目中不工作

为什么一个Test的instance?& gt;在构造函数中接受非空对象?

使用Mockito进行的Junit测试失败

Java Mooc.fi Part 12_01.Hideout -返回和删除方法

声明带有泛型的函数以用作查找映射中的值

为什么Collectors.toList()不能保证易变性

为什么有两种实现来检索数组类的组件类型?

将stringBuilder + forloop转换为stream + map

如何在字节数组中反转UTF-8编码?

Java嵌套流查找任意值

JPA无手术同品种器械可能吗?

验证没有';t work on Hibernate Entity';s字段

ControlsFX RangeSlider在方向垂直时滞后

JavaFX中ListView中的问题

Java中计算大n和k值模10^9+7的二项式系数的乘法公式输出错误值