We help IT Professionals succeed at work.

Java Code Error

Simon Leung
Simon Leung asked
on
I have encountered the following error when compiling the java code. Any idea ?

MyStack.java:76: error: non-static variable this cannot be referenced from a static context
        ArrayStack stack = new ArrayStack();MyStack.java
Comment
Watch Question

BRONZE EXPERT
Commented:
Yes, you either have to declare the variable static, OR create an instance of the class it's in, and then reference it.

public static void main(String[] args) {
	MyStack m = new MyStack();
    ArrayStack stack = m.new ArrayStack();
	   
    }

Open in new window

Author

Commented:
Thx, but where should I define the variable static ?
BRONZE EXPERT

Commented:
This error:
"non-static variable this cannot be referenced from a static context"
is Java being very unhelpful - because where is the "this" it's talking about?

The issue is that you have put multiple classes inside a single file - which means you've also put them inside another class "MyStack".

When you do this, by default Java makes these weird things called "inner classes" which contain secret references to the parent class.
In particular ArrayStack is an inner class of MyStack - which means an instance of ArrayStack requires to be built inside an instance of MyStack.

This whole "inner class" thing was almost certainly a mistake in the Java language (nobody else copied this in other languages) and the best way to really fix this error is to either:
a) Move each public class into a separate file  (this is what Java would like you to do)
or
b) Mark each public class that's inside MyStack with "static" (which simply means create a normal class, not an inner class here).

i.e.
      public static class StackEmptyException extends RuntimeException {
      public static class ArrayStack implements Stack {
      public static class StackFullException extends RuntimeException {

Either of those approaches should fix the problem.

You can read more about inner classes here:
https://docs.oracle.com/javase/tutorial/java/javaOO/innerclasses.html


Hope that helps,

Doug
BRONZE EXPERT

Commented:
Thx, but where should I define the variable static ?

 I didn't think you actually wanted to *achieve* static access - I read your question as you being surprised you couldn't instantiate an instance object right from the main method.
BRONZE EXPERT

Commented:
Course, there are other odd things going on here, such as ArrayStack's  :

public static final int CAPACITY = 1000;

which you can simply access from MyStack's main class, without needing any object creation. Just call System.out.println(ArrayStack.CAPACITY);

You may have good reason to do that sort of thing, but . . . why ? Is your code actually "real world", or simply an experiment in what's possible ?
BRONZE EXPERT

Commented:
I've hacked your code (at the expense of any useful involvement of the Exception calls) just to show how to call ArrayStack statically, whch was the other part of your earlier question.

public class MyStack {


public interface Stack {
	public void push( Object element );
	public Object pop()
		throws StackEmptyException;
	public int size();
	public boolean isEmpty();
	public Object top()
		throws StackEmptyException;
}

public  class StackEmptyException extends RuntimeException {
	public StackEmptyException( String err ) {
		super( err );
	}
}

public static class ArrayStack implements MyStack.Stack {
	public static final int CAPACITY = 1000;
	private int capacity;
	private Object S[];
	private int top = -1;
    

	public ArrayStack() {
		this( CAPACITY );
        System.out.println("ArrayStack constructor called.");
	}

	public ArrayStack( int cap ) {
		capacity = cap;
		S = new Object[ capacity ];
	}

	public int size() {
		return ( top + 1 );		
	}
public boolean isEmpty() {
		return( top < 0 );
	}

	public void push( Object obj ) throws StackFullException {
	if( size() == capacity )
		//throw new StackFullException( "Stack overflow" );
	S[ ++top ] = obj;
}

public Object top() throws StackEmptyException {
	if( isEmpty() ){}
		//throw new StackEmptyException( "Stack is empty." );
	return S[ top ];
}

public Object pop() throws StackEmptyException {
		Object elem;

		if( isEmpty() ){}
			//throw new StackEmptyException( "Stack is Empty." );
		elem = S[ top ];
		//System.out.println("");
		S[ top-- ] = null;

		return elem;
		
	}
		
}

public  class StackFullException extends RuntimeException {
	public StackFullException( String err ) {
		super( err );
	}
}

public static void main(String[] args) {
	//MyStack m = new MyStack();
    //ArrayStack stack = m.new ArrayStack();
	 ArrayStack stack = new ArrayStack();  
    }
	
}

Open in new window