statique - static java




Classe interne Java et classe imbriquée statique (16)

Classe imbriquée: classe à l'intérieur de la classe

Les types:

  1. Classe imbriquée statique
  2. Classe imbriquée non statique [Classe interne]

Différence:

Classe imbriquée non statique [Classe interne]

Dans l'objet de classe imbriqué non statique de la classe interne existe dans l'objet de la classe externe. Donc, ce membre de données de la classe externe est accessible à la classe interne. Donc, pour créer un objet de classe interne, nous devons d'abord créer un objet de classe externe.

outerclass outerobject=new outerobject();
outerclass.innerclass innerobjcet=outerobject.new innerclass(); 

Classe imbriquée statique

Dans l'objet de classe imbriqué statique de classe interne n'a pas besoin d'objet de classe externe, parce que le mot "statique" n'indique pas besoin de créer l'objet.

class outerclass A {
    static class nestedclass B {
        static int x = 10;
    }
}

Si vous voulez accéder à x, alors écrivez la méthode intérieure suivante

  outerclass.nestedclass.x;  i.e. System.out.prinltn( outerclass.nestedclass.x);

Quelle est la principale différence entre une classe interne et une classe imbriquée statique en Java? Le design / la mise en œuvre jouent-ils un rôle dans le choix de l'un d'entre eux?


Dans le cas de création d'instance, l'instance de classe interne non statique est créée avec la référence de l'objet de la classe externe dans laquelle elle est définie. Cela signifie qu'il a une instance inclinant. Mais l'instance de classe interne statique est créée avec la référence de classe externe, pas avec la référence d'objet de classe externe. Cela signifie qu'il n'a pas d'instance en instance.

Par exemple:

class A
{
  class B
  {
    // static int x; not allowed here…..    
  }
  static class C
  {
    static int x; // allowed here
  }
}

class Test
{
  public static void main(String… str)
  {
    A o=new A();
    A.B obj1 =o.new B();//need of inclosing instance

    A.C obj2 =new A.C();

    // not need of reference of object of outer class….
  }
}

En termes simples, nous avons besoin de classes imbriquées principalement parce que Java ne fournit pas de fermetures.

Les classes imbriquées sont des classes définies dans le corps d'une autre classe englobante. Ils sont de deux types - statiques et non statiques.

Ils sont traités en tant que membres de la classe englobante, vous pouvez donc spécifier l'un des quatre spécificateurs d'accès - private, package, protected, public . Nous n'avons pas ce luxe avec des classes de haut niveau, qui ne peuvent être déclarées public ou paquet-privé.

Classes internes aka Les classes non-stack ont ​​accès aux autres membres de la classe supérieure, même si elles sont déclarées privées alors que les classes imbriquées statiques n'ont pas accès aux autres membres de la classe supérieure.

public class OuterClass {
    public static class Inner1 {
    }
    public class Inner2 {
    }
}

Inner1 est notre classe interne statique et Inner2 est notre classe interne qui n'est pas statique. La différence clé entre eux, vous ne pouvez pas créer une instance Inner2 sans un Outer où vous pouvez créer un objet Inner1 indépendamment.

Quand utiliseriez-vous la classe interne?

Pensez à une situation dans laquelle la Class A et la Class B sont liées, la Class B doit avoir accès aux membres de la Class A et la Class B est liée uniquement à la Class A Les classes intérieures entrent en scène.

Pour créer une instance de classe interne, vous devez créer une instance de votre classe externe.

OuterClass outer = new OuterClass();
OuterClass.Inner2 inner = outer.new Inner2();

ou

OuterClass.Inner2 inner = new OuterClass().new Inner2();

Quand utiliseriez-vous la classe interne statique?

Vous devez définir une classe interne statique lorsque vous savez qu'elle n'a aucune relation avec l'instance de la classe / top class englobante. Si votre classe interne n'utilise pas les méthodes ou les champs de la classe externe, c'est juste une perte d'espace, alors faites-la statique.

Par exemple, pour créer un objet pour la classe imbriquée statique, utilisez cette syntaxe:

OuterClass.Inner1 nestedObject = new OuterClass.Inner1();

L'avantage d'une classe imbriquée statique est qu'elle n'a pas besoin d'un objet de la classe ou de la classe supérieure contenant pour fonctionner. Cela peut vous aider à réduire le nombre d'objets créés par votre application lors de l'exécution.


Il y a une subtilité à propos de l'utilisation de classes statiques imbriquées qui pourraient être utiles dans certaines situations.

Alors que les attributs statiques sont instanciés avant que la classe soit instanciée via son constructeur, les attributs statiques des classes statiques imbriquées ne semblent pas être instanciés avant que le constructeur de la classe ne soit invoqué, ou du moins après que les attributs aient été référencés. ils sont marqués comme 'définitifs'.

Considérez cet exemple:

public class C0 {

    static C0 instance = null;

    // Uncomment the following line and a null pointer exception will be
    // generated before anything gets printed.
    //public static final String outerItem = instance.makeString(98.6);

    public C0() {
        instance = this;
    }

    public String makeString(int i) {
        return ((new Integer(i)).toString());
    }

    public String makeString(double d) {
        return ((new Double(d)).toString());
    }

    public static final class nested {
        public static final String innerItem = instance.makeString(42);
    }

    static public void main(String[] argv) {
        System.out.println("start");
        // Comment out this line and a null pointer exception will be
        // generated after "start" prints and before the following
        // try/catch block even gets entered.
        new C0();
        try {
            System.out.println("retrieve item: " + nested.innerItem);
        }
        catch (Exception e) {
            System.out.println("failed to retrieve item: " + e.toString());
        }
        System.out.println("finish");
    }
}

Même si 'nested' et 'innerItem' sont tous les deux déclarés comme 'static final'. le paramètre de nested.innerItem n'a pas lieu tant que la classe n'est pas instanciée (ou du moins pas avant que l'élément statique imbriqué ne soit référencé), comme vous pouvez le constater en commentant et en décommentant les lignes auxquelles je me réfère, au dessus. La même chose n'est pas vraie pour 'outerItem'.

Au moins c'est ce que je vois dans Java 6.0.


Je ne pense pas que la vraie différence est devenue claire dans les réponses ci-dessus.

Premier à obtenir les termes corrects:

  • Une classe imbriquée est une classe contenue dans une autre classe au niveau du code source.
  • Il est statique si vous le déclarez avec le modificateur statique .
  • Une classe imbriquée non statique est appelée classe interne. (Je reste avec une classe imbriquée non statique.)

La réponse de Martin est juste pour le moment. Cependant, la vraie question est la suivante: quel est le but de déclarer une classe imbriquée statique ou non?

Vous utilisez des classes imbriquées statiques si vous souhaitez simplement conserver vos classes si elles appartiennent ensemble ou si la classe imbriquée est exclusivement utilisée dans la classe englobante. Il n'y a pas de différence sémantique entre une classe imbriquée statique et toutes les autres classes.

Les classes imbriquées non statiques sont une bête différente. Semblables à des classes internes anonymes, ces classes imbriquées sont en réalité des fermetures. Cela signifie qu'ils capturent leur portée environnante et leur instance englobante et la rendent accessible. Peut-être qu'un exemple éclaircira cela. Voir ce talon d'un conteneur:

public class Container {
    public class Item{
        Object data;
        public Container getContainer(){
            return Container.this;
        }
        public Item(Object data) {
            super();
            this.data = data;
        }

    }

    public static Item create(Object data){
        // does not compile since no instance of Container is available
        return new Item(data);
    }
    public Item createSubItem(Object data){
        // compiles, since 'this' Container is available
        return new Item(data);
    }
}

Dans ce cas, vous voulez avoir une référence d'un élément enfant au conteneur parent. En utilisant une classe imbriquée non statique, cela fonctionne sans travail. Vous pouvez accéder à l'instance englobante de Container avec la syntaxe Container.this .

Plus d'explications hardcore suivantes:

Si vous regardez les bytecodes Java que le compilateur génère pour une classe imbriquée (non statique), cela peut devenir encore plus clair:

// class version 49.0 (49)
// access flags 33
public class Container$Item {

  // compiled from: Container.java
  // access flags 1
  public INNERCLASS Container$Item Container Item

  // access flags 0
  Object data

  // access flags 4112
  final Container this$0

  // access flags 1
  public getContainer() : Container
   L0
    LINENUMBER 7 L0
    ALOAD 0: this
    GETFIELD Container$Item.this$0 : Container
    ARETURN
   L1
    LOCALVARIABLE this Container$Item L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 1
  public <init>(Container,Object) : void
   L0
    LINENUMBER 12 L0
    ALOAD 0: this
    ALOAD 1
    PUTFIELD Container$Item.this$0 : Container
   L1
    LINENUMBER 10 L1
    ALOAD 0: this
    INVOKESPECIAL Object.<init>() : void
   L2
    LINENUMBER 11 L2
    ALOAD 0: this
    ALOAD 2: data
    PUTFIELD Container$Item.data : Object
    RETURN
   L3
    LOCALVARIABLE this Container$Item L0 L3 0
    LOCALVARIABLE data Object L0 L3 2
    MAXSTACK = 2
    MAXLOCALS = 3
}

Comme vous pouvez le voir, le compilateur crée un champ caché Container this$0 . Ceci est défini dans le constructeur qui a un paramètre supplémentaire de type Container pour spécifier l'instance englobante. Vous ne pouvez pas voir ce paramètre dans la source mais le compilateur le génère implicitement pour une classe imbriquée.

L'exemple de Martin

OuterClass.InnerClass innerObject = outerObject.new InnerClass();

serait donc compilé à un appel de quelque chose comme (en bytecodes)

new InnerClass(outerObject)

Par souci d'exhaustivité:

Une classe anonyme est un exemple parfait d'une classe imbriquée non statique qui n'a aucun nom associé et ne peut pas être référencée plus tard.


Je pense qu'aucune des réponses ci-dessus ne vous explique la différence réelle entre une classe imbriquée et une classe imbriquée statique en termes de conception d'application:

OverView

Une classe imbriquée peut être non statique ou statique et dans chaque cas, une classe est définie dans une autre classe . Une classe imbriquée ne devrait exister que pour servir est une classe englobante , si une classe imbriquée est utile pour d'autres classes (et pas seulement pour l'inclusion), elle devrait être déclarée comme une classe de premier niveau.

Différence

Nonstatic Nested class : implicitement associé à l'instance englobante de la classe conteneur , cela signifie qu'il est possible d'appeler des méthodes et d'accéder à des variables de l'instance englobante. Une utilisation courante d'une classe imbriquée non statique consiste à définir une classe Adapter.

Classe imbriquée statique : impossible d'accéder à l'instance de classe englobante et aux méthodes d'invocation. Il convient donc de l'utiliser lorsque la classe imbriquée n'a pas besoin d'accéder à une instance de la classe englobante. Une utilisation courante de la classe imbriquée statique consiste à implémenter des composants de l'objet externe.

Conclusion

Donc, la différence principale entre les deux du point de vue de la conception est la suivante: la classe imbriquée non statique peut accéder à l'instance de la classe de conteneur, tandis que la statique ne le peut pas .


L'instance de la classe interne est créée lorsque l'instance de la classe externe est créée. Par conséquent, les membres et les méthodes de la classe interne ont accès aux membres et aux méthodes de l'instance (objet) de la classe externe. Lorsque l'instance de la classe externe est hors de portée, les instances internes de classe cessent également d'exister.

La classe imbriquée statique n'a pas d'instance concrète. C'est juste chargé quand il est utilisé pour la première fois (tout comme les méthodes statiques). C'est une entité complètement indépendante, dont les méthodes et les variables n'ont aucun accès aux instances de la classe externe.

Les classes imbriquées statiques ne sont pas couplées avec l'objet externe, elles sont plus rapides, et elles ne prennent pas de mémoire tas / pile, car il n'est pas nécessaire de créer une instance de telle classe. Par conséquent, la règle empirique consiste à essayer de définir une classe imbriquée statique, avec une portée aussi limitée que possible (private> = class> = protected> = public), puis de la convertir en classe interne (en supprimant l'identificateur "static") la portée, si c'est vraiment nécessaire.


La classe imbriquée est un terme très général: chaque classe qui n'est pas de niveau supérieur est une classe imbriquée. Une classe interne est une classe imbriquée non statique. Joseph Darcy a écrit une très belle explication sur les classes imbriquées, internes, membres et de premier niveau .


Les termes sont utilisés de manière interchangeable. Si vous voulez être vraiment pédant à ce sujet, alors vous pouvez définir "classe imbriquée" pour faire référence à une classe interne statique, qui n'a pas d'instance englobante. Dans le code, vous pourriez avoir quelque chose comme ceci:

public class Outer {
    public class Inner {}

    public static class Nested {}
}

Ce n'est pas vraiment une définition largement acceptée cependant.


Voici les principales différences et similitudes entre la classe interne Java et la classe imbriquée statique.

J'espère que cela aide!

Classe intérieure

  • Peut accéder aux méthodes et aux champs statiques de la classe externe
  • Associé à l'instance de la classe englobante pour l'instancier, il faut d'abord une instance de classe externe (notez le nouveau mot-clé):

    Outerclass.InnerClass innerObject = outerObject.new Innerclass();
    
  • Impossible de définir les membres statiques eux- mêmes

  • Impossible d' avoir une déclaration de classe ou d' interface

Classe imbriquée statique

  • Impossible d'accéder aux méthodes ou champs d' instance de classe externe

  • Non associé à une instance de la classe englobante So pour l'instancier:

    OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
    

Similitudes

  • Les deux classes Inner peuvent accéder même aux champs privés et aux méthodes de classe externe
  • Aussi la classe Outer a accès à des champs privés et des méthodes de classes internes
  • Les deux classes peuvent avoir un modificateur d'accès privé, protégé ou public

Pourquoi utiliser des classes imbriquées?

Selon la documentation Oracle, il existe plusieurs raisons ( documentation complète ):

  • C'est un moyen de grouper logiquement des classes qui ne sont utilisées que dans un seul endroit: Si une classe n'est utile qu'à une autre classe, il est logique de l'incorporer dans cette classe et de garder les deux ensemble. L'imbrication de ces "classes auxiliaires" rend leur paquet plus simple.

  • Cela augmente l'encapsulation: Considérons deux classes de niveau supérieur, A et B, où B doit avoir accès aux membres de A qui seraient autrement déclarés privés. En masquant la classe B dans la classe A, les membres A peuvent être déclarés privés et B peut y accéder. En outre, B lui-même peut être caché du monde extérieur.

  • Cela peut conduire à un code plus lisible et maintenable: l' imbrication de petites classes dans des classes de premier niveau place le code plus près de l'endroit où il est utilisé.


Inner class and nested static class in Java both are classes declared inside another class, known as top level class in Java. In Java terminology, If you declare a nested class static, it will called nested static class in Java while non static nested class are simply referred as Inner Class.

What is Inner Class in Java?

Any class which is not a top level or declared inside another class is known as nested class and out of those nested classes, class which are declared non static are known as Inner class in Java. there are three kinds of Inner class in Java:

1) Local inner class - is declared inside a code block or method.
2) Anonymous inner class - is a class which doesn't have name to reference and initialized at same place where it gets created.
3) Member inner class - is declared as non static member of outer class.

public class InnerClassTest {
    public static void main(String args[]) {      
        //creating local inner class inside method i.e. main() 
        class Local {
            public void name() {
                System.out.println("Example of Local class in Java");

            }
        }      
        //creating instance of local inner class
        Local local = new Local();
        local.name(); //calling method from local inner class

        //Creating anonymous inner class in Java for implementing thread
        Thread anonymous = new Thread(){
            @Override
            public void run(){
                System.out.println("Anonymous class example in java");
            }
        };
        anonymous.start();

        //example of creating instance of inner class
        InnerClassTest test = new InnerClassTest();
        InnerClassTest.Inner inner = test.new Inner();
        inner.name(); //calling method of inner class
    }

     //Creating Inner class in Java
    private class Inner{
        public void name(){
            System.out.println("Inner class example in java");
        }
    }
}

What is nested static class in Java?

Nested static class is another class which is declared inside a class as member and made static. Nested static class is also declared as member of outer class and can be make private, public or protected like any other member. One of the main benefit of nested static class over inner class is that instance of nested static class is not attached to any enclosing instance of Outer class. You also don't need any instance of Outer class to create instance of nested static class in Java .

1) It can access static data members of outer class including private.
2) Static nested class cannot access non-static (instance) data member or method .

public class NestedStaticExample {
    public static void main(String args[]){  
        StaticNested nested = new StaticNested();
        nested.name();
    }  
    //static nested class in java
    private static class StaticNested{
        public void name(){
            System.out.println("static nested class example in java");
        }
    }
}

Ref: Inner class and nested Static Class in Java with Example


First of all There is no such class called Static class.The Static modifier use with inner class (called as Nested Class) says that it is a static member of Outer Class which means we can access it as with other static members and without having any instance of Outer class. (Which is benefit of static originally.)

Difference between using Nested class and regular Inner class is:

OuterClass.InnerClass inner = new OuterClass().new InnerClass();

First We can to instantiate Outerclass then we Can access Inner.

But if Class is Nested then syntax is:

OuterClass.InnerClass inner = new OuterClass.InnerClass();

Which uses the static Syntax as normal implementation of static keyword.


I think people here should notice to Poster that : Static Nest Class just only the first inner class. Par exemple:

 public static class A {} //ERROR

 public class A {
     public class B {
         public static class C {} //ERROR
     }
 }

 public class A {
     public static class B {} //COMPILE !!!

 }

So, summarize, static class doesn't depend which class its contains. So, they cannot in normal class. (because normal class need an instance).


The difference is that a nested class declaration that is also static can be instantiated outside of the enclosing class.

When you have a nested class declaration that is not static, also known as an inner class , Java won't let you instantiate it except via the enclosing class. The object created out of the inner class is linked to the object created from the outer class, so the inner class can reference the fields of the outer.

But if it's static, then the link does not exist, the outer fields cannot be accessed (except via an ordinary reference like any other object) and you can therefore instantiate the nested class by itself.


Ummm... an inner class IS a nested class... do you mean anonymous class and inner class?

Edit: If you actually meant inner vs anonymous... an inner class is just a class defined within a class such as:

public class A {
    public class B {
    }
}

Whereas an anonymous class is an extension of a class defined anonymously, so no actual "class is defined, as in:

public class A {
}

A anon = new A() { /* you could change behavior of A here */ };

Further Edit:

Wikipedia claims there is a difference in Java, but I've been working with Java for 8 years, and it's the first I heard such a distinction... not to mention there are no references there to back up the claim... bottom line, an inner class is a class defined within a class (static or not), and nested is just another term to mean the same thing.

There is a subtle difference between static and non-static nested class... basically non-static inner classes have implicit access to instance fields and methods of the enclosing class (thus they cannot be constructed in a static context, it will be a compiler error). Static nested classes, on the other hand, don't have implicit access to instance fields and methods, and CAN be constructed in a static context.


When we declare static member class inside a class, it is known as top level nested class or a static nested class. It can be demonstrated as below :

class Test{
    private static int x = 1;
        static class A{
        private static int y = 2;
        public static int getZ(){
            return B.z+x;
        }
    }
    static class B{
        private static int z = 3;
        public static int getY(){
            return A.y;
        }
    }
}

class TestDemo{
     public static void main(String[] args){
        Test t = new Test();
        System.out.println(Test.A.getZ());
        System.out.println(Test.B.getY());
    }
}

When we declare non-static member class inside a class it is known as inner class. Inner class can be demonstrated as below :

    class Test{
        private int i = 10;
        class A{
            private int i =20;
            void display(){
            int i = 30;
            System.out.println(i);
            System.out.println(this.i);
            System.out.println(Test.this.i);
        }
    }
}




inner-classes