How to instantiate non static inner class within a static method?
Asked Answered
P

5

138

I have the following piece of code:

public class MyClass {

   class Inner {
     int s, e, p;
   }

   public static void main(String args[]) {
     Inner in;
   }
}

Up to this part the code is fine, but I am not able to instantiate 'in' within the main method like in = new Inner() as it is showing non static field cannot be referenced in static context.

What is the way I can do it? I do not want to make my Inner class static.

Plumley answered 2/10, 2012 at 12:21 Comment(2)
'Non-static inner' is a tautology.Trilingual
Well done on your Java knowledge. The title is expedient for search purposes.Neptunium
B
229

You have to have a reference to the other outer class as well.

Inner inner = new MyClass().new Inner();

If Inner was static then it would be

Inner inner = new MyClass.Inner();
Breve answered 2/10, 2012 at 12:22 Comment(3)
This answer just changed my outlook on life. outer.new Inner()? Never even considered it a possibility. O_OToffic
For static inner, can't you just simply do Inner inner = new Inner() ?Execration
@CanLu to create an object for static nested class, use OuterClass.StaticNestedClass nestedObj = new OuterClass.StaticNestedClass(). Nested ClassesBespangle
F
41

A "regular" inner class has a hidden (implicit) pointer to a Outer class instance. This allows the compiler to generate the code to chase the pointer for you without you having to type it. For instance, if there is a variable "a" in the outer class then the code in your inner class can just do "a=0", but the compiler will generate code for "outerPointer.a=0" maintaining the hidden pointer under the covers.

This means when you create an instance of an inner class you have to have an instance of a outer class to link it to. If you do this creation inside a method of the outer class then the compiler knows to use "this" as the implicit pointer. If you want to link to some other outer instance then you use a special "new" syntax (see code snippet below).

If you make your inner class "static" then there is no hidden pointer and your inner class cannot reference members of the outer class. A static inner class is identical to a regular class, but its name is scoped inside the parent.

Here is a snippet of code that demonstrates the syntax for creating static and non-static inner classes:

public class MyClass {

    int a,b,c; // Some members for MyClass

    static class InnerOne {
        int s,e,p;
        void clearA() {
            //a = 0;  Can't do this ... no outer pointer
        }
    }

    class InnerTwo {
        //MyClass parentPointer;      Hidden pointer to outer instance
        void clearA() {         
            a = 0;
            //outerPointer.a = 0      The compiler generates this code
        }       
    }

    void myClassMember() {
        // The compiler knows that "this" is the outer reference to give
        // to the new "two" instance.
        InnerTwo two = new InnerTwo(); //same as this.new InnerTwo()
    }

    public static void main(String args[]) {

        MyClass outer = new MyClass();

        InnerTwo x = outer.new InnerTwo(); // Have to set the hidden pointer
        InnerOne y = new InnerOne(); // a "static" inner has no hidden pointer
        InnerOne z = new MyClass.InnerOne(); // In other classes you have to spell out the scope

    }

}
Foghorn answered 2/10, 2012 at 13:25 Comment(0)
D
4

If you want to create new Inner() from within a method, do it from an instance method of the class MyClass:

public void main(){
  Inner inner = new Inner();
}

public static void main(String args[]){
  new MyClass().main();
}
Drama answered 2/10, 2012 at 13:15 Comment(0)
H
0

Alexei Kaigorodov's is the right answer. His solution allows you to instantiate inner classes from within a static method, such as a main() of the same class. Otherwise, you can't instantiate an inner class within a static method. It does not compile. Alexei's solution does compile and it does allow you to instantiate inner classes from a static method. The other answers are interesting side-notes, but I don't find them responsive to the actual question.

import java.awt.Graphics;
import java.awt.Color;
import javax.swing.JPanel;
import javax.swing.JFrame;

public class Example {
    public class InnerClass extends JPanel {
        public void paint(Graphics g) {
            g.setColor(Color.BLACK);
            g.fillRect(getX(),getY(),getWidth(),getHeight());
            g.setColor(Color.RED);
            g.fillRect(5, 20, 195, 20);
            g.setColor(Color.BLACK);
            g.drawString("This was written by an inner class.", 10, 35);
        }
    }

    public void demonstrate() {
        InnerClass sc = new InnerClass();//<---this is key
        JFrame jf = new JFrame();
        jf.add(sc);
        jf.setSize(220, 130);
        jf.setLocation(450, 450);
        jf.show();
    }

    public static void main(String[] params) {
        Example e = new Example();//<---so is this
        e.demonstrate();//<---and this is also key
    }
}
Habitforming answered 19/12, 2013 at 5:44 Comment(1)
Addendum: You -can- instantiate static inner classes from static methods. This sort of code is only needed to instantiate non-static inner classes from within static methods.Habitforming
D
-1

Static method link to class, do not have default this reference, so need explicit provide object. Instance method got this reference, so no need to provide object

Desdemona answered 8/3, 2023 at 2:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.