Statik bir yöntem içinde statik olmayan iç sınıf nasıl başlatılır?


122

Aşağıdaki kod parçasına sahibim:

public class MyClass {

   class Inner {
     int s, e, p;
   }

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

Bu bölüme kadar kod gayet iyi, ancak in = new Inner()gösterdiği gibi ana yöntem içinde 'in' örneğini oluşturamıyorum non static field cannot be referenced in static context.

Bunu yapmanın yolu nedir? InnerSınıfımı statik yapmak istemiyorum .


Yanıtlar:


201

Diğer dış sınıfa da başvurmanız gerekir.

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

İç statik olsaydı, o zaman olurdu

Inner inner = new MyClass.Inner();

53
Bu cevap hayata bakış açımı değiştirdi. external.new Inner ()? Bunu bir olasılık olarak hiç düşünmedim. O_O
AlbeyAmakiir

1
Statik iç için, sadece İç iç = yeni İç () yapamaz mısınız?
Can Lu

1
@CanLu statik iç içe sınıf için bir nesne oluşturmak için kullanın OuterClass.StaticNestedClass nestedObj = new OuterClass.StaticNestedClass(). Yuvalanmış Sınıflar
LittleLittleQ

37

"Normal" bir iç sınıfın bir Outer sınıf örneğine gizli (örtük) bir işaretçisi vardır. Bu, derleyicinin siz yazmanıza gerek kalmadan işaretçiyi sizin için kovalaması için kodu oluşturmasına olanak tanır. Örneğin, dış sınıfta bir "a" değişkeni varsa, o zaman iç sınıfınızdaki kod sadece "a = 0" yapabilir, ancak derleyici, "OuterPointer.a = 0" için kod oluşturacaktır. Örtüler.

Bu, bir iç sınıfın bir örneğini oluşturduğunuzda, onu bağlamak için bir dış sınıf örneğine sahip olmanız gerektiği anlamına gelir. Bu yaratımı dış sınıfın bir yöntemi içinde yaparsanız, derleyici "this" i örtük işaretçi olarak kullanmayı bilir. Başka bir dış örneğe bağlanmak istiyorsanız, özel bir "yeni" sözdizimi kullanırsınız (aşağıdaki kod parçacığına bakın).

İç sınıfınızı "statik" yaparsanız, gizli işaretçi yoktur ve iç sınıfınız dış sınıfın üyelerine başvuramaz. Statik bir iç sınıf, normal bir sınıfla aynıdır, ancak adı kapsamı üst sınıfın içindedir.

Statik ve statik olmayan iç sınıflar oluşturmak için sözdizimini gösteren bir kod parçacığı:

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

    }

}

4

Eğer yaratmak istiyorsan new Inner()Bir yöntem içinden , bunu sınıfın bir örnek yönteminden yapın MyClass:

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

public static void main(String args[]){
  new MyClass().main();
}

0

Alexei Kaigorodov'unki doğru cevap. Onun çözümü, aynı sınıfın main () gibi bir statik yöntem içinden iç sınıfları başlatmanıza izin verir. Aksi takdirde, bir statik yöntem içinde bir iç sınıfın örneğini oluşturamazsınız. Derlemez. Alexei'nin çözümü derleme yapar ve iç sınıfları statik bir yöntemden başlatmanıza izin verir. Diğer yanıtlar ilginç yan notlar, ancak onları asıl soruya yanıt verebilecek bulmuyorum.

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

Ek: Statik yöntemlerden statik iç sınıfları -can- somutlaştırabilirsiniz. Bu tür bir kod, yalnızca statik olmayan iç sınıfları statik yöntemler içinden somutlaştırmak için gereklidir.
Herbert Samuel Jennings III
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.