如何在静态方法中实例化非静态内部类?


122

我有以下代码:

public class MyClass {

   class Inner {
     int s, e, p;
   }

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

到目前为止,代码还不错,但是我无法像in = new Inner()显示的那样在main方法中实例化“ in” non static field cannot be referenced in static context

我该怎么做?我不想使我的Inner课堂静止


Answers:


201

您还必须参考其他外部类。

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

如果内在是静态的,那将是

Inner inner = new MyClass.Inner();

53
这个答案改变了我的人生观。external.new Inner()?甚至从未考虑过这种可能性。O_O
AlbeyAmakiir 2014年

1
对于静态内部,难道您不只是简单地执行Inner inner = new Inner()吗?
可以鲁

1
@CanLu为静态嵌套类创建一个对象,使用OuterClass.StaticNestedClass nestedObj = new OuterClass.StaticNestedClass()嵌套类
LittleLittleQ

37

“常规”内部类具有指向外部类实例的隐藏(隐式)指针。这使编译器可以生成代码来为您寻找指针,而无需键入它。例如,如果外部类中有一个变量“ a”,那么内部类中的代码只能执行“ a = 0”,但是编译器将为“ outerPointer.a = 0”生成代码,并在其中保留隐藏指针封面。

这意味着在创建内部类的实例时,必须具有外部类的实例才能将其链接到。如果在外部类的方法中进行此创建,则编译器会知道将“ this”用作隐式指针。如果要链接到其他外部实例,则可以使用特殊的“新”语法(请参见下面的代码段)。

如果将内部类设置为“静态”,则没有隐藏的指针,并且内部类无法引用外部类的成员。静态内部类与常规类相同,但其名称的作用域位于父类内部。

这是一段代码,演示了创建静态和非静态内部类的语法:

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

    }

}


0

阿列克谢·凯戈罗多夫(Alexei Kaigorodov)的答案是正确的。他的解决方案使您可以从静态方法中实例化内部类,例如同一类的main()。否则,您将无法在静态方法中实例化内部类。它不会编译。Alexei的解决方案确实可以编译,并且确实允许您从静态方法实例化内部类。其他答案都是有趣的旁注,但我发现它们对实际问题没有反应。

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
    }
}

附录:您可以从静态方法实例化静态内部类。仅从静态方法内部实例化非静态内部类时才需要这种代码。
赫伯特·塞缪尔·詹宁斯三世
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.