5

The following code snippet throws the error: " Generic array creation" despite not having any generic instances within the Node class. However, if i declare the private class Node as static , the error goes away. Why is the static keyword important here?

 public class SeperateChainingST<Key, Value>{

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

        private class Node{
            Object key;
            Object val;
            Node next;
        }
    }
deepak
  • 375
  • 1
  • 3
  • 8
  • do not you need to define Node class first and use it after? – Kick Buttowski Dec 11 '14 at 05:07
  • I don't believe this code does this. – chrylis -cautiouslyoptimistic- Dec 11 '14 at 05:08
  • 2
    @KickButtowski No, Java doesn't have obnoxious forward-declaration rules. – chrylis -cautiouslyoptimistic- Dec 11 '14 at 05:08
  • @chrylis wowwwwwww cool always learn something new thank you :) – Kick Buttowski Dec 11 '14 at 05:11
  • 1
    Maybe this will help you a little http://stackoverflow.com/a/26452098/1393766. In short you could try to use `private SeperateChainingST.Node[] st = new SeperateChainingST.Node[M];` but using raw types is discouraged. Instead you should use collection like `private List.Node> list = new ArrayList<>();` – Pshemo Dec 11 '14 at 05:24
  • Also consider actually changing types of Node fields `key`, `val` to actually use generic types of your `SeperateChainingST` class (otherwise what is the point of having them?). So instead of `Object` you can use `Key key`, `Value val`. – Pshemo Dec 11 '14 at 05:28
  • @Pshemo But using generic types for array creation is disallowed in Java. It throws the same exception: "Generic array creation" error – deepak Dec 11 '14 at 05:29
  • 2
    I didn't use generic type while creating array, I used raw type (which is considered as errorprone so compiler give us *warning* about it, not *error*). I used then with lists. – Pshemo Dec 11 '14 at 05:31
  • 1
    @Pshemo I will try this with Lists then. Thanks! – deepak Dec 11 '14 at 05:36

1 Answers1

5

Node is a non-static nested class. That means it is an inner class, and it is within the scope of the type parameters Key and Value of its outer class.

When you simply write the type Node without any explicitly qualification inside SeperateChainingST, it is implicitly qualified as SeperateChainingST<Key, Value>.Node. This is a parameterized type (it has the type parameters Key and Value), even though you do not "see" them when writing Node.

As you know, you cannot use array creation expression with a component type that is a parameterized type:

new HashMap<Key, Value>[5]

So you cannot do

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

But, as you may also know, array creation expression can be used with a component type that is a raw type, or a type that is parameterized with all wildcards:

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

We can do it similarly here, except how do you get the raw type of the inner class Node? It is not just Node, as we have found. Instead, you must explicitly qualify it with the raw type of the outer class:

new SeperateChainingST.Node[5]

or with the all-wildcards way:

new SeperateChainingST<?,?>.Node[5]
user207421
  • 305,947
  • 44
  • 307
  • 483
newacct
  • 119,665
  • 29
  • 163
  • 224