Ravi
Ravi

Reputation: 153

Java inner class using outer class' parameterized type

Im creating an inner class in Java that uses outer class' parameterized types as instance fields. Now when I try to create an arrayof this innerclass, I get classcast exception

 class ModdedSeperateChainingAlternate<Key, Value> extends SeperateChainingHashST<Key, Value> {

    int N;
    int M;
    Node[] list = (Node[]) new Object[M]; //  classcast exception

    class Node {
        Node next;
        Key key;
        Value value;
        int n;

        public Node(Key k, Value v, Node next) {
            this.key = k;
            this.value = v;
            this.next = next;
        }
        ......
    }

Please advice me on how to get around this. Im a generics noob

Upvotes: 1

Views: 470

Answers (2)

newacct
newacct

Reputation: 122439

Node is a non-static nested class. That means it is within the scope of the type parameter of the outer class, and is effectively "parameterized" by that type parameter even though it is not directly on Node.

When you write a bare Node inside ModdedSeperateChainingAlternate, it implicitly means ModdedSeperateChainingAlternate<Key, Value>.Node, which is a parameterized type. You cannot create an array of a parameterized type, e.g. You cannot do new ArrayList<String>[M]; for the same reason, you cannot do new Node[M] (which is equivalent to new ModdedSeperateChainingAlternate<Key, Value>.Node[M]).

Instead, you can do either:

  • create an array of the raw type, like new ArrayList[M]. But how do you write the raw type in this case? It is not Node as we have seen. Instead, you have to explicitly qualify it with the raw outer type:

    Node[] list = new ModdedSeperateChainingAlternate.Node[M];
    
  • or, create an array of the type parameterized with all wildcards, like new ArrayList<?>[M]. In this case, it would be:

    Node[] list = (Node[])new ModdedSeperateChainingAlternate<?, ?>.Node[M];
    

Upvotes: 1

Magnilex
Magnilex

Reputation: 11958

You are casting an Object[] to a Node[]:

Node[] list = (Node[]) new Object[M]; //  classcast exception

The straightforward solution is to just create a Node[] instead:

Node[] list = new Node[M];

However, this fails due to the reason explained here:

Cannot create a generic array of TWTestCase.ModdedSeperateChainingAlternate.Node

So, to achieve your goal, you need to use some Collection instead, preferably a List:

List<Node> list = new ArrayList<Node>(M);

And while you are at it, instance variables should be camel case according to Java standards:

int m;

And further, int m will have the default integer value, which is 0. In other words you will create a zero-length array. Make sure the varaible is initialized (e.g. int i = 5).

As for the generics part, Node derives its types from ModdedSeperateChainingAlternate<Key, Value>. You can read more about generics here.

Upvotes: 4

Related Questions