Bagaimana cara membuat instance kelas dalam non statis dalam metode statis?


122

Saya memiliki potongan kode berikut:

public class MyClass {

   class Inner {
     int s, e, p;
   }

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

Sampai bagian ini kodenya baik-baik saja, tetapi saya tidak dapat memberi contoh 'in' dalam metode utama seperti in = new Inner()yang ditunjukkan non static field cannot be referenced in static context.

Bagaimana cara saya melakukannya? Saya tidak ingin membuat Innerkelas saya statis .


Jawaban:


201

Anda harus memiliki referensi ke kelas luar lainnya juga.

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

Jika Inner statis maka itu akan terjadi

Inner inner = new MyClass.Inner();

53
Jawaban ini baru saja mengubah pandangan saya tentang hidup. outer.new Inner ()? Bahkan tidak pernah menganggapnya sebagai kemungkinan. O_O
AlbeyAmakiir

1
Untuk bagian dalam statis, tidak bisakah Anda hanya melakukan Inner inner = new Inner ()?
Can Lu

1
@CanLu untuk membuat objek untuk kelas bertingkat statis, gunakan OuterClass.StaticNestedClass nestedObj = new OuterClass.StaticNestedClass(). Kelas Bersarang
LittleLittleQ

37

Kelas dalam "biasa" memiliki penunjuk tersembunyi (implisit) ke instance kelas Luar. Ini memungkinkan kompilator untuk menghasilkan kode untuk mengejar penunjuk untuk Anda tanpa Anda harus mengetiknya. Misalnya, jika ada variabel "a" di kelas luar maka kode di kelas dalam Anda bisa melakukan "a = 0", tetapi kompilator akan menghasilkan kode untuk "outerPointer.a = 0" dengan mempertahankan pointer tersembunyi di bawah selimut.

Ini berarti ketika Anda membuat instance dari kelas dalam, Anda harus memiliki instance kelas luar untuk ditautkan. Jika Anda melakukan pembuatan ini di dalam metode kelas luar maka kompilator tahu untuk menggunakan "ini" sebagai penunjuk implisit. Jika Anda ingin menautkan ke beberapa contoh luar lainnya, maka Anda menggunakan sintaks "baru" khusus (lihat cuplikan kode di bawah).

Jika Anda membuat kelas dalam Anda "statis" maka tidak ada pointer tersembunyi dan kelas dalam Anda tidak dapat mereferensikan anggota kelas luar. Kelas dalam statis identik dengan kelas reguler, tetapi namanya dicakup di dalam induk.

Berikut adalah cuplikan kode yang menunjukkan sintaks untuk membuat kelas dalam statis dan non-statis:

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

Jika Anda ingin membuat new Inner()dari dalam metode, lakukan dari metode instance kelas MyClass:

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

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

0

Jawaban Alexei Kaigorodov adalah jawaban yang tepat. Solusinya memungkinkan Anda untuk membuat instance kelas dalam dari dalam metode statis, seperti main () dari kelas yang sama. Jika tidak, Anda tidak dapat membuat instance kelas dalam dalam metode statis. Itu tidak dapat dikompilasi. Solusi Alexei dapat dikompilasi dan memungkinkan Anda untuk membuat instance kelas dalam dari metode statis. Jawaban lain adalah catatan sampingan yang menarik, tetapi saya tidak menganggapnya responsif terhadap pertanyaan yang sebenarnya.

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

Tambahan: Anda -dapat- membuat instance kelas dalam statis dari metode statis. Kode semacam ini hanya diperlukan untuk membuat instance kelas dalam non-statis dari dalam metode statis.
Herbert Samuel Jennings III
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.