136 votes

Comment instancier non statique à l'intérieur de la classe dans une méthode statique

J'ai le morceau de code suivant:

public class MyClass{
   class Inner{
     int s,e,p;
   }

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

Jusqu'à cette partie du code est très bien, mais je ne suis pas en mesure d'instancier 'dans' l'intérieur de la méthode comme in=new Inner() que c'est en montrant non static field cannot be referenced in static context. Qu'est-ce que la façon dont je peux le faire? Je ne veux pas faire mon Intérieur de la classe statique.

228voto

RNJ Points 5820

Vous devez avoir une référence à l'autre extérieur de la classe.

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

Si l'Intérieur est statique alors il serait

Inner inner = new MyClass.Inner();

41voto

ChrisCantrell Points 828

Un "régulier" intérieur de la classe a un caché (implicite) pointeur vers un parent de la classe de l'instance. Cela permet au compilateur de générer le code pour chasser le pointeur pour vous, sans que vous ayez à taper. Par exemple, si il y a une variable "a" dans la classe parent le code dans votre intérieur de la classe suffit de le faire "a=0", mais le compilateur va générer du code pour "parentPointer.a=0" maintenir le pointeur caché sous les couvertures.

Cela signifie que lorsque vous créez une instance de l'un à l'intérieur de la classe, vous devez avoir une instance d'une classe parent d'un lien. Si vous n'cette création à l'intérieur d'une méthode de la classe parente, puis le compilateur sait utiliser "ce" que l'implicite pointeur. Si vous souhaitez mettre un lien vers un autre parent de l'instance, puis vous utilisez un spécial "nouvelle" syntaxe (voir l'extrait de code ci-dessous).

Si vous faire de votre intérieur de la classe "statique" il n'est pas caché pointeur et l'intérieur de votre classe ne peut pas référencer les membres de la classe parent. Un statique à l'intérieur de la classe est identique à une classe ordinaire, mais son nom est étendue à l'intérieur de la mère.

Voici un extrait de code suivant illustre la syntaxe de création d'statiques et non statiques de classes internes:

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

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

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

    public static void main(String args[]) {

        MyClass parent = new MyClass();

        InnerTwo x = parent.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

    }

}

4voto

Alexei Kaigorodov Points 5841

Si vous souhaitez créer new Inner() à partir de l'intérieur d'une méthode, le faire à partir d'une méthode d'instance de la classe MyClass:

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

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

0voto

Alexei Kaigorodov est la bonne réponse. Sa solution permet d'instancier les classes internes de l'intérieur d'une méthode statique, comme une main() de la même classe. Sinon, vous ne pouvez pas instancier un à l'intérieur de la classe dans une méthode statique. Il ne compile pas. Alexei la solution de ne compiler et elle ne vous permet pas d'instancier les classes internes à partir d'une méthode statique. Les autres réponses sont intéressantes côté-notes, mais je ne les trouve pas sensible à la 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
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X