Caffeinated
Caffeinated

Reputation: 12478

Why do I get the "non-static variable this cannot be referenced from a static context" error only when I have inner classes?

I'm struggling on the concept of static vs. non-static. I'm studying this Thread example program(modified, from here originally), and when I use inner classes I will get the error:

Error: non-static variable this cannot be referenced from a static context

Here is the error-causing code:

public class Main2 {
    public static void main(String[] args) {
        Thread simple = new Thread(new SimpleTask());
        simple.start();
    }


    class SimpleTask implements Runnable {
        public void run() {

        }

        ;
    }

    class DaemonTask implements Runnable {
        public void run() {
            int i = 0;
        }
    }

}

However, when I break it out so that it's 3 classes, there's no error.. ie if I make it:

public class Main2 {  
   /* contents */  
}

class SimpleTask implements Runnable {
   /* contents */
}

class DaemonTask implements Runnable {
   /* contents */
}

Then it compiles just fine. Why does it matter that we split it out into another class?

Upvotes: 3

Views: 3550

Answers (5)

Jeff
Jeff

Reputation: 159

The issue is in the line "Thread simple = new Thread(new SimpleTask());" As the class SimpleTask is defined as a nested class, you need an object of the outer class to create one (the constructor essentially requires an implicit reference to the containing class, similar to how normal methods get an implicit reference to the current class instance as 'this'). What you are essentially asking for here is "Thread simple = new Thread(null.new SimpleTask());" and it's this 'null' which is causing the exception.

Upvotes: 1

Anirudha
Anirudha

Reputation: 32787

SimpleTask and DemonTask class should be static


Instance members(in your case SimpleTask and DemonTask) are associated with the particular object of class.And so you can't use instance members directly within static method(becuase static members don't have any information about the instances of class unless you pass the instance itself as parameter)

You have to either create an object of Main2 and access SimpleTask and DemonTask through it new Main2().new SimpleTask()

OR

make those two classes static

Upvotes: 1

lucian.pantelimon
lucian.pantelimon

Reputation: 3669

Try and make class SimpleTask implements Runnable static.

When you declare a class like that, you are declaring somewhat of a per-instance class definition. To be more precise, you are tying the class definition of SimpleTask to an instance of Main2.

In order to instantiate an object of that class you would do:

Main2 obj = new Main2();
SimpleTask t = obj.new SimpleTask();

Notice the use of obj.new. When you call that from inside your outer class, you are really calling this.new. Static methods have no knowledge of this, so you get an error.

Upvotes: 1

PermGenError
PermGenError

Reputation: 46408

you need an outer class instance(Main2) to access inner class instance(SimpleTask).

Try this:

    Thread simple = new Thread(new Main2().new SimpleTask());

Check Inner class on Oracle trails

Upvotes: 4

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272467

Because your classes are non-static inner classes; they implicitly need a corresponding instance of the outer class.

Declare your inner classes as static, and your issue should go away.

Upvotes: 3

Related Questions