tags:

views:

101

answers:

4

I created a non-static inner class like this:

class Sample {
    public void sam() {
        System.out.println("hi");
    }    
}

I called it in main method like this:

Sample obj = new Sample();
obj.sam();

It gave a compilation error: non-static cannot be referenced from a static context When I declared the non-static inner class as static, it works. Why is that so?

+1  A: 

Maybe this will help : http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html the non-static inner class cannot be called in a static context (in your example there is no instance of the outer class).

Vinze
+3  A: 

A non-static inner class has the outer class as an instance variable, which means it can only be instantiated from such an instance of the outer class:

public class Outer{
    public class Inner{
    }

    public void doValidStuff(){
         Inner inner = new Inner();
         // no problem, I created it from the context of *this*
    }

    public static void doInvalidStuff(){
         Inner inner = new Inner();
         // this will fail, as there is no *this* in a static context
    }

}
seanizer
This is NOT true. See my own answer here
Eugene Kuleshov
everything I wrote is true but the word 'only'. and in a perfect world, that should also be true, because the instantiation mentioned in your answer is awful style.
seanizer
@Eugene, your answer does not refute this... you have a new A() in your answer which exactly correspond to what seanizer mean by "can only be instantiated from such an instance". And I must agree, this is awful style...
Vinze
@seanizer, your statement "can only be instantiated from such an instance of the outer class" is misleading and my example is showing that it can be instantiated from outside of the outer class, even so outer instance is created and it does indeed look odd, the Java syntax does allow that. Essentially "new" can be treated as a "special" method call. Awful or not is part of the Java grammar.
Eugene Kuleshov
+1  A: 

For a non-static inner class, the compiler automatically adds a hidden reference to the "owner" object instance. When you try to create it from a static method (say, the main method), there is no owning instance. It is like trying to call an instance method from a static method - the compiler won't allow it, because you don't actually have an instance to call.

So the inner class must either itself be static (in which case no owning instance is required), or you only create the inner class instance from within a non-static context.

Ash
+2  A: 

An inner class needs an instance of the outer class, because there is an implicit constructor generated by compiler. However you can get around it like the following:

public class A {

  public static void main(String[] args) {
    new A(). new B().a();
  }

  class B {
    public void a() {
      System.err.println("AAA");
    }
  }

}
Eugene Kuleshov
arghhh, this is awful style and leads to almost unmaintainable code!!!
seanizer
No one is suggesting if this should be used or not. That wasn't what original question was asking.
Eugene Kuleshov
when a beginner asks a question like that a request for guidance to best practices is IMO implied. There are many language features that tend to confuse beginners (like dynamic initializer blocks etc) and I think they shouldn't be mentioned to a beginner until he specifically asks for them
seanizer