java - 无法创建通用数组

标签 java generics

我收到以下代码的错误“无法创建通用数组”:

public class MapImpl<K, V> {
    private static int DEFAULT_CAPACITY = 16;

    private int size;
    // array holding the entries of the map
    private Entry[] entries;

    public MapImpl() {
        entries = new Entry[DEFAULT_CAPACITY]; // error at this line: Cannot create a generic array of MapImpl<K,V>.Entry
    }

    // represents an entry in the map
    private class Entry {
        private K key;
        private V value;

        public Entry(K key, V value) {
            this.key = key;
            this.value = value;
        }
    }

令人惊讶的是,这工作正常:

public class MapImpl<K, V> {
    private static int DEFAULT_CAPACITY = 16;

    private int size;
    // array holding the entries of the map
    private Entry<K, V>[] entries;

    public MapImpl() {
        entries = new Entry[DEFAULT_CAPACITY];
    }

    // represents an entry in the map
    private class Entry<K, V> {
        private K key;
        private V value;
//but here K and V are being hidden.
        public Entry(K key, V value) {
            this.key = key;
            this.value = value;
        }
    }

    }

I do understand that we can't create an array of generic type or a type that takes type parameters. But, here in my code the Entry class is not of a generic type. Am i overlooking something ?

最佳答案

这里的问题是非静态嵌套类可以访问其外部类的所有成员,其中包括有关外部类中使用的泛型类型的信息,例如

class Outer<T>{
    private T t;
    class Inner{
        void method(T tt){//we can use same type T as used in outer class
            t = tt;
        }
    }
}

所以在现实中Inner类类型更像是 Outer<T>.Inner这使得它的形式成为泛型类型,并且由于类型删除,数组不能从泛型类型创建,这将阻止数组测试添加的元素是否有效。

在这种情况下,最常见的解决方案是使用集合而不是像 List<OurType> 这样的数组。 .

但是如果你真的只想拥有数组那么其他可能的解决方案(但你应该尽量避免它)是使用原始类型,所以而不是

new Entry[DEFAULT_CAPACITY];

相当于

new MapImpl<K, V>.Entry[DEFAULT_CAPACITY];

你可以用

new MapImpl.Entry[DEFAULT_CAPACITY];
//         ^no generic type -> it is raw type

解决方案

private class Entry<K, V> {
    private K key;
    private V value;
//but here K and V are being hidden.
    public Entry(K key, V value) {
        this.key = key;
        this.value = value;
    }
}

工作可能(我找不到任何相关的 JLS 描述这个)因为正如你所说,你已经隐藏了原始 KV来自外部类,这意味着您现在无法访问它们

        void method(T tt){
            t = tt;
        }

方法不会编译因为T来自内部类与 T 不同来自外部类。正因为如此,Entry不再是 MapImpl<K,V>.Entry但是MapImpl.Entry<K,V>当你把它写成

new Entry[...]

你明确地使它成为原始类型,这将起作用(当你声明 private Entry[] entries 时有关于原始类型的编译警告)

关于java - 无法创建通用数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30029071/

相关文章:

java - 不兼容的类型将返回静态类型的泛型方法

java - 在抽象基类中使用 Java 泛型

java - 如何删除另一个线程正在使用的文件?

JAVA AND OR 和 IF

java - Hibernate - 每个操作的 ThreadLocal<EntityManager> 与 EntityManager

java - 如何将组合框值设置为列表中的选项之一

c# - 协变地交换列表中的两个元素

c# - 生成某个给定类型的通用列表

c# - T 不包含 RowKey 的定义

java - 注入(inject)枚举作为依赖项失败并出现 IllegalArgumentException,可能是由于代理所致