-4
public class stackofints<Item>
{
    private static node topofstack=null;

    private static class node{
        Item item;
        node next;
    }

    public static void push(Item item){
        node oldtopofstack=topofstack;
        topofstack=new node();
        topofstack.item=item;
        topofstack.next=oldtopofstack;
    }
    public static int pop(){
        Item item=topofstack.item;
        topofstack=topofstack.next;
        return item;
    }
    public boolean isEmpty(){return topofstack==null;}
    public static Item size(){
        Item i=0;
        node iterate=topofstack;
        while(iterate!=null)
        {
            iterate=iterate.next;
            i++;
        }
        return i;
    }

    public static void main(String[] args)
    {
        push(1);
        push(2);
        push(3);
        System.out.println(size());

    }

}

In the above code I am trying to use generic type but I get a compilation error:

File: D:\Java Code\stackofints.java [line: 6]
Error: non-static type variable Item cannot be referenced from a static context.

Can somebody help me resolve this issue. Thanks

Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
Goku
  • 57
  • 6

4 Answers4

1

Your class declares a type variable named "Item". It is not the name of a class, but only a placeholder allowing instances of the stackofints class to replace it with any type they want.

(As a sidenote, it is bad style to name those type variables ("placeholders") as if they were classes, because it is confusing. You should name it something like T instead : class stackofints<T>. Also, please name your classes in Camel-case, with an uppercase first letter : class StackOfInts<T>)

For example, you could have those instances :

stackofints<Integer> foo = new stackofints<>();  // Here, "Item" = Integer
stackofints<String>  bar = new stackofints<>();  // Now,  "Item" = String

So you see that the value of "Item" is specific to each instance, not to the class itself.

Now, you are trying to refer to this value from a static field. By definition, a static field belongs to the class itself, not to a specific instance.

That is why the compiler complains : you are trying to refer uniquely to something that can have multiple values.

Olivier Croisier
  • 6,139
  • 25
  • 34
0

Generics in Java != Templates, you cannot do what you try to do in a static class. During runtime whatever Item was will be reduced to Object thus there cannot be a static instance of T in MyType<T> and a resolution of said instance during runtime (since every T is reduced to Object).

Solution: make everything instanced (non-static) and a singleton of your type.

BeyelerStudios
  • 4,243
  • 19
  • 38
0

At compile time, generics allow a type to be plugged when instantiating an object, and then can ensure that all future uses of the object use the object correctly.

Prior to generics: List myList = new ArrayList(); Integer i = (Integer) myList.get(1);

With generics: List myList = new ArrayList<>(); Integer i = myList.get(1);

Without generics, there's a lot of casting and a lot of ClassCastExceptions at runtime; with generics, you wouldn't make it past compilation.

With your code, you're trying to use the generic in static methods. However, static methods don't require object instantiation, and therefore have no context. I can create a List, List, List, the static method would have no idea which to use, hence it's illegal.

Also, the design of this class, with essentially nothing but static methods, seems suspect, and you might want to revisit.

Scott Sosna
  • 1,443
  • 1
  • 8
  • 8
0

First of all, the error you are receiving deals with attempting to associate your type parameter Item that is bound to your stackofints class. This type parameter is only allowed to be reference in a non-static context. You need to define a type parameter in your node class. These names should be different to avoid confusion.

Now, there are a couple things wrong with your code.

  1. Your topofstack variable should be an instance variable, so it should not be declared static.
  2. Your push, pop, and size methods should not be static as they should be asscociated with an instance of a stackofints object.
  3. You do not create an instance of stackofints in your main method.
  4. You do not provide a generic type for your node class.
  5. The size() method should always returns an int, the generic type does not matter.
  6. By not adhering to Java syntax standards, you are making it difficult for others to interpret your code.

This code below is the correct way to accomplish what your are trying to achieve.

public class NodeStack<T> {
    private Node<T> topOfStack = null;

    private static class Node<I> {
        I item;
        Node<I> next;
    }

    public void push(T item) {
        Node<T> oldTopOfStack = topOfStack;
        topOfStack = new Node<T>();
        topOfStack.item = item;
        topOfStack.next = oldTopOfStack;
    }

    public T pop() {
        T item = topOfStack.item;
        topOfStack = topOfStack.next;
        return item;
    }

    public boolean isEmpty() {
        return topOfStack == null;
    }

    public int size() {
        int i = 0;
        Node<T> iterate = topOfStack;
        while (iterate != null) {
            iterate = iterate.next;
            i++;
        }
        return i;
    }

    public static void main(String[] args) {
        NodeStack<Integer> stackOfIntegers = new NodeStack<Integer>();
        stackOfIntegers.push(1);
        stackOfIntegers.push(2);
        stackOfIntegers.push(3);
        System.out.println(stackOfIntegers.size());
    }
}
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132