为什么我需要声明一个私有类静态来避免“通用数组创建”错误?

5
以下代码片段会抛出错误:"Generic array creation",尽管Node类中没有任何泛型实例。但是,如果我将私有类Node声明为静态的,则错误消失了。为什么在这里使用static关键字很重要?
 public class SeperateChainingST<Key, Value>{

        private int M =97;
        private Node[] st = new Node[M];

        private class Node{
            Object key;
            Object val;
            Node next;
        }
    }

2
@KickButtowski 不,Java没有令人讨厌的前向声明规则。 - chrylis -cautiouslyoptimistic-
1
也许这会对你有所帮助 http://stackoverflow.com/a/26452098/1393766。简而言之,你可以尝试使用 private SeperateChainingST.Node[] st = new SeperateChainingST.Node[M]; 但是使用原始类型是不被鼓励的。相反,你应该使用集合,如 private List<SeperateChainingST<Key, Value>.Node> list = new ArrayList<>(); - Pshemo
@Pshemo 但是在Java中,使用通用类型创建数组是不允许的。它会抛出相同的异常:“Generic array creation”错误。 - deepak
2
我在创建数组时没有使用泛型类型,而是使用了原始类型(这被认为是容易出错的,因此编译器会对此发出警告而不是错误)。然后我在列表中使用了它们。 - Pshemo
1
@Pshemo 我会尝试使用列表。谢谢! - deepak
显示剩余4条评论
1个回答

5

Node是一个非静态嵌套类。这意味着它是一个内部类,并且在其外部类的类型参数KeyValue的范围内。

当你在SeperateChainingST中简单地写下类型Node而没有任何明确的限定时,它会被隐式地限定为SeperateChainingST<Key, Value>.Node。这是一个参数化类型(它具有类型参数KeyValue),即使在写Node时你不“看到”它们。

正如你所知道的,你不能使用一个组件类型为参数化类型的数组创建表达式:

new HashMap<Key, Value>[5]

因此,您不能这样做。

new Node[5] // which is equivalent to
new SeperateChainingST<Key, Value>.Node[5]

但是,正如您可能知道的那样,数组创建表达式可以与组件类型为原始类型或使用所有通配符进行参数化的类型一起使用:

new HashMap[5]
new HashMap<?,?>[5]

我们可以在这里类似地做,但是你如何获得内部类 Node 的原始类型?它不仅仅是 Node,正如我们所发现的。相反,你必须明确地使用外部类的原始类型来限定它:

new SeperateChainingST.Node[5]

或者采用全通配符方式:
new SeperateChainingST<?,?>.Node[5]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接