0

I am implementing an interface in Java like this:

public interface Stack <E>{
    public int size();
    public boolean isEmpty();

the class that implements it:

public class StackArray<E> implements Stack<E>{
    private Object list[];
    private int top=-1;
    public StackArray(int n){
        list=new Object[n];
    }

this works quite well, so when I called it I do this:

public static void main(String[] args) {
        // TODO code application logic here
        StackArray<Students> st=new StackArray<>(4);

so how I can implement that, but using generics, I have tried this:

public class StackArray<E> implements Stack<E>{
    private E st[];
    private int top=-1;
    public StackArray(int n){
        st=(E[]) Array.newInstance(null, n);
    }

but I got a nullPointerException, is there a way to surpase this?

Little
  • 2,841
  • 6
  • 33
  • 57
  • Which line throws the `NPE`? – ssantos Oct 13 '13 at 16:05
  • 1
    I would suspect that the line `Array.newInstance(null, n);` throws the NPE, especially given that the [javadoc](http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Array.html#newInstance(java.lang.Class,%20int)) says that it will... – Boris the Spider Oct 13 '13 at 16:06

2 Answers2

1

Because of type erasure, you at some point need to pass the actual class (or an actual object from which the class can be obtained via getClass()) when creating an array of objects. You cannot pass null as the first argument to Array.newInstance; you need an actual class. One way to do it is:

public class StackArray<E> implements Stack<E>{
    private E st[];
    private int top=-1;
    public StackArray(Class<E> type, int n) {
        st=(E[]) Array.newInstance(type, n);
    }
}

You would need to call this with the actual type, not null. For instance:

StackArray<Integer> stack = new StackArray<>(Integer.class, 20);

You could also declare the constructor as

    public StackArray(Class<? extends E> type, int n) {

but I don't see much advantage to that (and several risks).

However, in general it's a bad idea to mix arrays with generics. I suggest you rethink your design.

Ted Hopp
  • 222,293
  • 47
  • 371
  • 489
0

You cannot create generic arrays in Java.

You are getting a NullPointerException because of this line:

Array.newInstance(null, n);

From the Javadoc for that method:

Parameters:
    componentType - the Class object representing the component type of the new array
    length - the length of the new array
Returns:
    the new array
Throws:
    NullPointerException - if the specified componentType parameter is null
    IllegalArgumentException - if componentType is Void.TYPE
    NegativeArraySizeException - if the specified length is negative

You can see that it states that it will throw a NullPointerException if componentType is null.

One hack is to create an Object[] and then cast it:

public StackArray(int n){
    st=(E[]) new Object[n];
}

I said hack because this is horrible and should be avoided. The best thing you can do is use the java collections API and change your class to

public class StackArray<E> implements Stack<E>{
    private List<E> st;
    private int top=-1;

    public StackArray(int n){
        st = new ArrayList<E>(n);
    }

    //...
}
Boris the Spider
  • 54,398
  • 6
  • 98
  • 152