Classe intérieure Java et classe statique imbriquée

Quelle est la principale différence entre une classe intérieure et une classe statique imbriquée en Java? N'conception / mise en œuvre de jouer un rôle dans le choix d'un de ces?

1506
demandé sur Micha Sprengers 2008-09-16 12:22:35

24 réponses

De la Java Tutoriel :

les classes imbriquées sont divisées en deux catégories: statiques et non statiques. Classes imbriquées qui sont déclarées statiques sont simplement appelés statique classes imbriquées. Les classes imbriquées Non statiques sont appelées classes intérieures.

les classes statiques imbriquées sont accessibles en utilisant le nom de classe qui les entoure:

OuterClass.StaticNestedClass

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

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

les objets qui sont des instances d'une classe interne existent dans une instance de la classe externe. Considérons les classes suivantes:

class OuterClass {
    ...
    class InnerClass {
        ...
    }
}

une instance D'InnerClass ne peut exister que dans une instance D'OuterClass et a un accès direct aux méthodes et aux champs de son instance enveloppante.

pour instancier une classe intérieure, vous devez d'abord instancier l'extérieur classe. Ensuite, créez l'objet intérieur dans l'objet extérieur avec cette syntaxe:

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

voir: tutoriel Java - classes imbriquées

par souci d'exhaustivité, il convient de noter qu'il existe également un élément tel que classe intérieure sans une instance enveloppante :

class A {
  int t() { return 1; }
  static A a =  new A() { int t() { return 2; } };
}

ici, new A() { ... } est une classe intérieure définie dans un contexte statique et n'a pas d'instance enveloppante.

1511
répondu Martin 2017-05-23 12:10:47

le tutoriel Java dit :

terminologie: les classes imbriquées sont divisés en deux catégories: statique et non statique. Des classes imbriquées qui sont déclarées statiques sont simplement appelés classes statiques imbriquées. Non statique les classes imbriquées s'appellent inner classe.

dans le langage courant, les Termes "imbriqué" et" interne " sont utilisés de façon interchangeable par la plupart des programmeurs, mais je vais utiliser le terme correct "classe imbriquée", qui couvre à la fois intérieure et statique.

les Classes peuvent être imbriquées ad infinitum , p.ex. la classe a peut contenir la Classe B qui contient la Classe C qui contient la classe D, etc. Cependant, plus d'un niveau de classe de nidification est rare, car il est généralement de mauvaise conception.

il y a trois raisons pour lesquelles vous pouvez créer une classe imbriquée:

  • organisation: il semble parfois plus raisonnable pour trier une classe dans l'espace de noms d'une autre classe, surtout quand il ne sera pas utilisé dans un autre contexte
  • accès: les classes imbriquées ont un accès spécial aux variables/champs de leurs classes contenant (précisément quelles variables/champs dépendent du type de classe imbriquée, interne ou statique).
  • commodité: avoir à créer un nouveau fichier pour chaque nouveau type est gênant, encore une fois, surtout quand le type ne seront utilisées que dans un contexte

il y a quatre types de classe imbriquée en Java . En bref, ils sont:

  • classe statique : déclarée comme membre statique d'une autre classe
  • classe intérieure : déclarée comme instance membre d'une autre classe
  • classe intérieure locale : déclarée à l'intérieur d'une instance méthode de une autre classe
  • anonymous inner class : comme une classe intérieure locale, mais écrite comme une expression qui renvoie un objet unique

permettez-moi d'élaborer plus en détail.



Classes Statiques

les classes statiques sont les plus faciles à comprendre parce qu'elles n'ont rien à voir avec les instances du containing classe.

d'Une classe statique est une classe déclarée en tant que membre statique d'une autre classe. Tout comme les autres membres statiques, une telle classe est vraiment juste un cintre sur qui utilise la classe contenant comme son espace de nom, par exemple la classe chèvre déclaré comme un membre statique de la classe Rhino dans le paquet pizza est connu sous le nom pizza.Rhino.Chèvre .

package pizza;

public class Rhino {

    ...

    public static class Goat {
        ...
    }
}

franchement, les classes statiques sont une fonctionnalité sans grande valeur parce que les classes sont déjà divisées en namespaces par paquets. La seule vraie raison concevable pour créer une classe statique est qu'une telle classe a accès aux membres statiques privés de sa classe contenant, mais je trouve que c'est une justification assez boiteuse pour la caractéristique de classe statique d'exister.



Classes Intérieures

une classe intérieure est une classe déclarée comme membre non statique d'une autre classe:

package pizza;

public class Rhino {

    public class Goat {
        ...
    }

    private void jerry() {
        Goat g = new Goat();
    }
}

comme pour une classe statique, la classe intérieure est qualifiée par son nom de classe contenant, pizza.Rhino.Chèvre , mais à l'intérieur de la classe containing, il peut être connu par son nom simple. Cependant, chaque instance d'une classe intérieure est liée à une instance particulière de sa classe contenant: ci-dessus, le chèvre créé en jerry , est implicitement lié au Rhino instance ce dans jerry . Sinon, nous rendons l'instance associée Rhino explicite lorsque nous instancions chèvre :

Rhino rhino = new Rhino();
Rhino.Goat goat = rhino.new Goat();

(notez que vous vous référez au type intérieur comme juste chèvre dans le bizarre nouveau syntaxe: Java déduit le type contenant de la partie rhino . Et, oui nouveau rhinocéros.Chèvre() aurait fait plus de sens pour moi aussi.)

qu'est-ce que cela nous apporte? Eh bien, l'instance de classe interne a accès aux membres de l'instance de classe contenant. Ces membres d'instance enveloppants sont mentionnés à l'intérieur de la classe intérieure via juste leurs noms simples, pas via ce ( ce dans l'intérieur de la classe se réfère à l'intérieur de la classe, par exemple, pas les associés contenant de l'instance de classe):

public class Rhino {

    private String barry;

    public class Goat {
        public void colin() {
            System.out.println(barry);
        }
    }
}

dans la classe intérieure, vous pouvez vous référer à ce de la classe contenant comme Rhino.ce , et vous pouvez utiliser ce pour se référer à ses membres, e.g. Rhinocéros.ce.barry .



Classes Intérieures Locales

une classe intérieure locale est une classe déclarée dans le corps d'une méthode. Une telle classe n'est connue que dans sa méthode containing, de sorte qu'elle ne peut être instanciée et avoir ses membres accessibles dans sa méthode containing. Le gain est qu'une instance de classe interne locale est liée et peut accéder aux variables locales finales de sa méthode containing. Lorsque l'instance utilise un local final de son contenant la méthode, la variable conserve la valeur qu'elle détenait au moment de la création de l'instance, même si la variable est sortie de sa portée (il s'agit en fait de la version brute et limitée de Java des fermetures).

parce qu'une classe intérieure locale n'est pas membre d'une classe ou d'un paquet, elle n'est pas déclarée avec un niveau d'accès. (Il faut toutefois préciser que ses propres membres ont des niveaux d'accès comparables à ceux d'une classe normale.)

si une classe intérieure locale est déclarée en une méthode d'instance, une instanciation de la classe interne est liée à l'instance détenue par la méthode contenant cette au moment de la création de l'instance, et donc les membres de l'instance de la classe contenant sont accessibles comme dans une classe interne d'instance. Une classe intérieure locale est instanciée simplement via son nom, e.g. classe intérieure locale Cat est instanciée comme nouvelle Cat() , pas nouveau.Cat () as you might expect.



Classes Intérieures Anonymes

une classe intérieure anonyme est une façon syntaxiquement commode d'écrire une classe intérieure locale. Le plus souvent, une classe interne locale est instanciée au plus juste une fois chaque fois que sa méthode contenant est exécutée. Ce serait bien, alors, si nous pouvions combiner la définition de classe interne locale et sa instanciation unique dans une forme syntaxique commode, et ce serait aussi bien si nous n'avions pas à trouver un nom pour la classe (le moins de noms inutiles que votre code contient, le mieux). Une classe intérieure anonyme permet ces deux choses:

new *ParentClassName*(*constructorArgs*) {*members*}

c'est une expression retournant une nouvelle instance d'une classe sans nom qui s'étend nom de Parentclass . Vous ne pouvez pas fournir votre propre constructeur; plutôt, un est implicitement fourni qui appelle simplement le super constructeur, donc les arguments fournis doivent correspondre au super constructeur. (Si le parent contient plusieurs constructeurs, le "plus simple" est appelé, "plus simple" comme déterminé par un ensemble de règles plutôt complexe ne vaut pas la peine de se donner la peine d'apprendre en détail--juste faire attention à ce que NetBeans ou Eclipse vous disent.)

alternativement, vous pouvez spécifier une interface à implémenter:

new *InterfaceName*() {*members*}

une Telle déclaration crée une nouvelle instance d'une classe sans nom qui étend objet et met en œuvre InterfaceName . Encore une fois, vous ne pouvez pas fournir votre propre constructeur; dans ce cas, Java fournit implicitement un constructeur no-arg, do-nothing (il n'y aura donc jamais d'arguments de constructeur dans ce cas).

même si vous ne pouvez pas donner de constructeur à une classe interne anonyme, vous pouvez toujours faire n'importe quelle configuration que vous voulez en utilisant un bloc initialiseur (un bloc {} placé en dehors de n'importe quelle méthode).

être clair qu'un la classe interne anonyme est tout simplement une manière moins flexible de créer une classe interne locale avec une instance. Si vous voulez une classe interne locale qui implémente des interfaces multiples ou qui implémente des interfaces tout en étendant une classe autre que Object ou qui spécifie son propre constructeur, vous êtes bloqué en créant une classe interne locale nommée régulière.

531
répondu Jegschemesch 2017-08-04 08:40:03

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

Premiers à obtenir les conditions de droit:

  • Une classe imbriquée est une classe qui est 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 intérieure. (Je reste avec les non-statique imbriquée classe.)

la réponse de Martin est correcte jusqu'à présent. Cependant, la question qui se pose est la suivante: à quoi sert de déclarer une classe imbriquée statique ou non?

Vous utilisez statique classes imbriquées si vous voulez garder vos classes si elles appartiennent topique ensemble, ou si la classe imbriquée est exclusivement utilisé dans la classe englobante. Il n'y a pas de différence sémantique entre une classe imbriquée statique et une autre classe.

Non-statique classes imbriquées sont une autre bête. Tout comme les classes internes anonymes, ces classes imbriquées sont en fait des fermetures. Cela signifie qu'ils capturent leur portée environnante et leur instance enveloppante et les rendent accessibles. Peut-être un exemple permettra de clarifier cela. Voir ce talon de 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 du conteneur parent. À l'aide d'un classe non statique imbriquée, ça marche sans travail. Vous pouvez accéder à L'instance enveloppante du conteneur avec la syntaxe Container.this .

explications plus hardcore suivantes:

si vous regardez les bytecodes Java générés par le compilateur pour une classe imbriquée (non statique), cela pourrait 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"151910920"

  // access flags 1
  public getContainer() : Container
   L0
    LINENUMBER 7 L0
    ALOAD 0: this
    GETFIELD Container$Item.this"151910920" : 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"151910920" : 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"151950920" . Ceci est défini dans le constructeur qui a un paramètre supplémentaire de type conteneur pour spécifier l'instance d'enclos. Vous ne pouvez pas voir ce paramètre dans la source, mais le compilateur génère implicitement pour une classe imbriquée.

Martin exemple

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

serait ainsi 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 tout simplement pas de nom associé à elle et ne peut pas être référencée plus tard.

126
répondu jrudolph 2013-08-27 07:53:39

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 de l'application:

vue d'ensemble

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

différence

classe imbriquée nonstatique : est implicitement associée à l'instance enveloppante de la classe containing, ce qui signifie qu'il est possible d'invoquer des méthodes et des variables d'accès de l'instance enveloppante. Une utilisation courante d'une classe imbriquée non statique est de définir une classe D'Adaptateur.

Classe statique imbriquée : ne peut pas accéder à une instance de classe enveloppante et invoquer des méthodes sur elle, donc devrait être utilisé lorsque la classe imbriquée n'a pas besoin d'accéder à une instance de la classe enveloppante . Une utilisation courante de la classe statique imbriquée est de mettre en œuvre un composant de l'objet extérieur.

Conclusion

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

83
répondu aleroot 2015-02-28 23:47:23

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 à l'intérieur du corps d'une autre classe. Ils sont de deux types statiques et non statiques.

ils sont traités comme des membres de la classe enclosante, donc vous pouvez spécifier n'importe lequel 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és public ou package-private.

classes intérieures aka Non-stack classes ont accès à d'autres membres de la classe supérieure, même si elles sont déclarées privées tandis que les classes imbriquées statiques n'ont pas accès à d'autres membres de la classe supérieure.

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

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

quand utiliserez-vous Inner class?

pensez à une situation où Class A et Class B sont liés, Class B doit accéder Class A membres, et Class B est lié seulement à Class A . Les classes intérieures entrent en ligne de compte.

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 intérieure statique?

vous définiriez une classe intérieure statique quand vous savez qu'elle n'a pas de relation avec l'instance de la classe enveloppante/classe supérieure. Si votre classe intérieure n'utilise pas de méthodes ou de champs de la classe extérieure, c'est juste un gaspillage d'espace, alors rendez-le statique.

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

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

l'avantage d'une classe statique imbriquée est qu'elle n'a pas besoin d'un objet de la classe containing/top class pour fonctionner. Cela peut vous aider à réduire le nombre d'objets que votre application crée à l'exécution.

29
répondu Thalaivar 2017-01-02 05:15:01

je pense, la convention qui est généralement suivie est celle-ci:

  • classe statique à l'intérieur d'une classe de haut niveau est une classe imbriquée
  • non static class dans une classe de niveau supérieur est une classe intérieure , qui en outre a deux plus de forme:
    • classe locale - classes nommées déclarées à l'intérieur d'une bloc comme une méthode ou un corps de constructeur
    • classe anonyme - sans nom des classes dont les instances sont créées dans des expressions et des états

cependant, peu d'autres points à retenir sont:

  • les classes supérieures et les classes statiques imbriquées sont sémantiquement identiques, sauf que dans le cas d'une classe statique imbriquée elles peuvent faire référence statique aux champs/méthodes statiques privés de sa classe externe [parent] et vice versa.

  • les classes internes ont accès aux variables d'instance de l'instance enveloppante de la classe externe [parent]. Cependant, toutes les classes internes n'ont pas d'instances d'inclusion, par exemple les classes internes dans des contextes statiques, comme une classe anonyme utilisée dans un bloc d'initialisation statique, ne le font pas.

  • classe Anonyme par par défaut, étend la classe parent ou implémente l'interface parent et il n'y a plus de clause pour étendre une autre classe ou implémenter d'autres interfaces. Donc,

    • new YourClass(){}; signifie class [Anonymous] extends YourClass {}
    • new YourInterface(){}; signifie class [Anonymous] implements YourInterface {}

je pense que la grande question qui reste ouverte, laquelle utiliser et quand? Bien que cela dépend surtout du scénario auquel vous faites face, mais la lecture de la réponse donnée par @jrudolph pourrait vous aider à prendre une décision.

24
répondu sactiw 2013-01-24 05:40:10

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

Espère que cela aide!

Intérieure

  • Peuvent accéder à à l'extérieur de la classe instance et statique les méthodes et les champs
  • associé à l'instance d'enfermement classe afin de l'instancier premiers besoins une instance de la classe extérieure (note nouveau place du mot-clé):

    Outerclass.InnerClass innerObject = outerObject.new Innerclass();
    
  • ne peut pas définir tout membres statiques lui-même

  • Ne peut pas ont Classe ou Interface déclaration

Statique de la classe imbriquée

  • ne peut accéder à classe extérieure instance méthodes ou champs

  • non associé à une instance ayant entouré la classe afin de l'instancier:

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

similitudes

  • les deux classes intérieures peut accéder même méthodes et champs privés de classe extérieure
  • également la Classe extérieure ont accès à champs privés et méthodes de classes intérieures 1519140920"
  • les deux classes peuvent avoir un modificateur d'accès privé, protégé ou public

Pourquoi Utiliser Des Classes Imbriquées?

selon Oracle documentation il y a plusieurs raisons ( documentation complète ):

  • c'est une façon de regrouper logiquement des classes qui ne sont utilisées qu'à un seul endroit: si une classe est utile à une seule autre classe, alors il est logique de l'intégrer dans cette classe et de garder les deux ensembles. L'imbrication de telles" classes d'assistants " rend leur paquet plus simple.

  • il augmente encapsulation: envisager deux classes de haut niveau, A et B, où B a besoin d'accéder aux membres de A qui autrement serait déclaré privé. En cachant la Classe B dans la classe A, Les membres de 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.

  • il peut conduire à un code plus lisible et maintenable: nicher petites classes dans les classes supérieures, le code est plus proche de l'endroit où il est utilisé.

23
répondu Behzad Bahmanyar 2017-04-26 07:39:52

classe imbriquée: classe intérieure

:

  1. Statique de la classe imbriquée
  2. classe imbriquée Non statique [Classe intérieure]

différence:

Non-statique de la classe imbriquée [Intérieure]

dans la classe non statique imbriquée, l'objet de la classe intérieure existe dans l'objet de la classe extérieure. Donc ce membre de données de la classe externe est accessible à l'intérieur de la classe. Donc, pour créer un objet de classe intérieure, nous devons créer un objet de classe extérieure en premier.

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

Statique de la classe imbriquée

dans la classe statique imbriquée, objet de la classe intérieure n'a pas besoin d'objet de la classe extérieure, car le mot" statique " indique qu'il n'est pas nécessaire de créer un objet.

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

si vous voulez accéder à x, alors écrivez la méthode suivante à l'intérieur

  outerclass.nestedclass.x;  i.e. System.out.prinltn( outerclass.nestedclass.x);
13
répondu tejas 2015-05-10 23:57:03

l'instance de la classe intérieure est créée lorsque l'instance de la classe extérieure est créée. Par conséquent, les membres et les méthodes de la classe intérieure ont accès aux membres et aux méthodes de l'instance (objet) de la classe extérieure. Lorsque l'instance de la classe extérieure sort de son champ d'application, les instances de la classe intérieure cessent également d'exister.

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

les classes statiques imbriquées ne sont pas couplées avec l'objet extérieur, elles sont plus rapides, et elles ne prennent pas de mémoire tas/pile, parce qu'il n'est pas nécessaire de créer une instance d'une telle classe. Par conséquent, la règle de base est d'essayer de définir la classe statique imbriquée, avec une portée aussi limitée que possible (privé > = classe > = protégé > = public), puis, convertissez-le en classe intérieure (en supprimant l'identificateur "statique") et relâchez la portée, si c'est vraiment nécessaire.

10
répondu rmaruszewski 2008-09-16 08:58:40

il y a une subtilité dans l'utilisation de classes statiques imbriquées qui pourrait être utile dans certaines situations.

alors que les attributs statiques sont instanciés avant que la classe ne soit instanciée via son constructeur, les attributs statiques à l'intérieur des classes statiques imbriquées ne semblent pas être instanciés avant que le constructeur de classe est invoqué, ou du moins pas avant que les attributs ne soient référencés pour la première fois, même s'ils sont marqués comme "final".

considérons 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 "imbriqué" et "innerItem" sont tous deux déclarés "final statique". paramètre de imbriqués.innerItem n'a pas lieu jusqu'à ce que la classe soit instanciée (ou au moins pas avant que l'élément statique imbriqué soit d'abord référencé), comme vous pouvez le voir par vous-même en commentant et en décommentant les lignes que je fais référence, ci-dessus. La même chose ne tient pas vrai pour "outerItem".

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

10
répondu HippoMan 2010-03-26 12:48:47

dans le cas de la création d'instance, l'instance de non la classe intérieure statique est créée avec la référence objet de la classe extérieure dans laquelle il est défini. Ce signifie qu'il a une instance inclosing. Mais l'exemple de la classe intérieure statique est créé avec la référence de la classe extérieure, pas avec la référence de l'objet de la classe extérieure. Cela signifie qu'il n'ont pas inclus l'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….
  }
}
9
répondu Ankit Jain 2013-11-14 12:43:57

Je ne pense pas qu'il y ait beaucoup à ajouter ici, la plupart des réponses expliquent parfaitement les différences entre les classes statiques imbriquées et les classes intérieures. Cependant, tenez compte de la question suivante lorsque vous utilisez des classes imbriquées par rapport à des classes internes. Comme la mention dans un couple de réponses classes internes ne peut pas être instancié sans et l'instance de leur classe d'enclos qui signifient qu'ils tiennent a pointeur à l'instance de leur classe d'enclos qui peut mener à un débordement de la mémoire ou à une exception de débordement de la pile en raison du fait que le GC ne sera pas en mesure de collecter les ordures des classes enveloppantes, même si elles ne sont plus utilisées. Pour que ce soit clair, cochez le code suivant:

public class Outer {


    public  class Inner {

    }


    public Inner inner(){
        return new Inner();
    }

    @Override
    protected void finalize() throws Throwable {
    // as you know finalize is called by the garbage collector due to destroying an object instance
        System.out.println("I am destroyed !");
    }
}


public static void main(String arg[]) {

    Outer outer = new Outer();
    Outer.Inner inner = outer.new Inner();

    // out instance is no more used and should be garbage collected !!!
    // However this will not happen as inner instance is still alive i.e used, not null !
    // and outer will be kept in memory until inner is destroyed
    outer = null;

    //
    // inner = null;

    //kick out garbage collector
    System.gc();

}

si vous supprimez le commentaire sur // inner = null; le programme mettra je suis détruit ! ", mais en gardant ceci commenté il ne sera pas.

La raison est que l'instance interne blanche est toujours le GC référencé ne peut pas le collecter et parce qu'il renvoie (a un pointeur vers) l'instance externe il n'est pas collecté aussi. Avoir assez de ces objets dans votre projet et peut manquer de mémoire.

Par rapport aux classes intérieures statiques qui ne tiennent pas un point à l'instance de classe intérieure parce qu'elle n'est pas liée à l'instance mais à la classe. Le programme ci-dessus peut imprimer " je suis détruit ! " si vous faites la classe intérieure statique et instantiated avec Outer.Inner i = new Outer.Inner();

9
répondu Adelin 2016-11-15 09:27:24

Les termes sont utilisés de façon interchangeable. Si vous voulez être vraiment pédant à ce sujet, alors vous pourrait définir "classe imbriquée" pour se référer à une classe interne statique, une qui n'a pas d'instance enveloppante. En 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.

7
répondu Daniel Spiewak 2008-09-16 08:25:42

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 intérieure est une classe non statique imbriquée. Joseph Darcy a écrit une très belle explication sur niché, intérieur, membre, et les Classes de haut niveau .

7
répondu Wouter Coekaerts 2012-08-03 02:31:14

Ummm... une classe intérieure est une classe imbriquée... tu veux dire la classe anonyme et la classe interne?

Edit: si vous vouliez réellement dire inner vs anonymous... une classe intérieure est juste une classe définie dans une classe telle que:

public class A {
    public class B {
    }
}

alors qu'une classe anonyme est une extension d'une classe définie de manière anonyme, aucune classe réelle n'est définie, comme dans:

public class A {
}

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

Modifier:

Wikipedia prétend qu'il y a une différence en Java, mais je travaille avec Java depuis 8 ans, et c'est la première fois que j'entends une telle distinction... sans compter qu'il n'y a aucune référence là-bas pour étayer la réclamation... en bref, une classe intérieure est une classe définie au sein d'une classe (statique ou non), et emboîté est juste un autre terme pour signifier la même chose.

il y a une différence subtile entre la classe statique et la classe non statique imbriquée... essentiellement non statique interne les classes ont un accès implicite aux champs d'instance et aux méthodes de la classe enveloppante (elles ne peuvent donc pas être construites dans un contexte statique, ce sera une erreur de compilation). Les classes statiques imbriquées, d'un autre côté, n'ont pas d'accès implicite aux champs d'instance et aux méthodes, et peuvent être construites dans un contexte statique.

6
répondu Mike Stone 2014-11-28 03:49:57

ciblant les apprenants novices en Java et/ou les Classes imbriquées

les classes imbriquées peuvent être:

1. Classes statiques imbriquées.

2. Classes imbriquées Non statiques. (également connu sous le nom de classes intérieures ) =>s'il Vous Plaît rappelez-vous de ce



1.Classes intérieures

Exemple:

class OuterClass  {
/*  some code here...*/
     class InnerClass  {  }
/*  some code here...*/
}



les classes intérieures sont des sous-ensembles de classes imbriquées:

  • la classe intérieure est un type spécifique de classe imbriquée
  • les classes intérieures sont des sous-ensembles de classes imbriquées
  • Vous pouvez dire qu'un intérieur de la classe est aussi une classe imbriquée, mais vous pouvez PAS dire qu'une classe imbriquée est également une classe intérieure .

spécialité de la classe intérieure:

  • instance d'une classe intérieure a accès à tous des membres de la classe extérieure, même ceux qui sont marqués "privé "



2.Classes Statiques Imbriquées:

Exemple:

class EnclosingClass {
  static class Nested {
    void someMethod() { System.out.println("hello SO"); }
  }
}

Cas 1:l'Instanciation d'une classe statique de la classe imbriquée à partir d'un non-classe englobante

class NonEnclosingClass {

  public static void main(String[] args) {
    /*instantiate the Nested class that is a static
      member of the EnclosingClass class:
    */

    EnclosingClass.Nested n = new EnclosingClass.Nested(); 
    n.someMethod();  //prints out "hello"
  }
}

Cas 2:l'Instanciation d'une classe statique de la classe imbriquée à partir d'une classe englobante

class EnclosingClass {

  static class Nested {
    void anotherMethod() { System.out.println("hi again"); } 
  }

  public static void main(String[] args) {
    //access enclosed class:

    Nested n = new Nested(); 
    n.anotherMethod();  //prints out "hi again"
  }

}

spécialité des classes statiques:

  • Statique à l'intérieur de la classe n'ont accès qu'aux membres statiques de l'extérieur de la classe, et n'ont pas accès à les membres non statiques.

Conclusion:

Question: Quelle est la principale différence entre une classe intérieure et une classe statique imbriquée en Java?

réponse: il suffit de passer en revue les caractéristiques de chaque classe mentionnée ci-dessus.

6
répondu VedX 2015-11-06 21:47:56

Classe intérieure et classe statique imbriquée en Java tous les deux sont des classes déclarées dans une autre classe, connue sous le nom de classe de premier niveau en Java. Dans la terminologie Java, si vous déclarez une classe imbriquée statique, elle sera appelée classe imbriquée statique en Java alors que la classe imbriquée non statique est simplement appelée classe interne.

Qu'est-ce que la classe intérieure en Java?

toute classe qui n'est pas un top niveau ou déclaré dans une autre classe est connu comme classe imbriquée et parmi ces classes imbriquées, classe qui sont déclarés non statique sont connus comme classe interne en Java. il existe trois types de classe intérieure en Java:

1) classe intérieure locale - est déclarée à l'intérieur d'un bloc de codes ou d'une méthode.

2) classe interne anonyme - est une classe qui n'a pas de nom à référencer et initialisée au même endroit où elle est créée.

Trois) Membre de la classe intérieure - est déclaré comme membre non statique de la classe extérieure.

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");
        }
    }
}

Qu'est-ce que la classe statique emboîtée en Java?

classe statique imbriquée est une autre classe qui est déclarée à l'intérieur d'une classe comme membre et rendue statique. La classe statique imbriquée est également déclarée comme membre de la classe extérieure et peut être rendue privée, publique ou protégée comme n'importe quel autre membre. L'un des principaux avantages de la classe statique imbriquée par rapport à la classe intérieure est cette instance de classe statique emboîtée n'est pas attachée à une instance enveloppante de classe extérieure. vous n'avez pas non plus besoin d'une instance de classe externe pour créer une instance de classe statique imbriquée en Java .

1) Il peut accéder à membres de données statiques de la classe extérieure y compris privée.

2) La classe statique imbriquée ne peut pas accéder à la méthode non-static (instance) data member ou .

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");
        }
    }
}

Réf: Classe intérieure et classe statique emboîtée en Java avec Exemple

5
répondu roottraveller 2017-03-22 10:39:26

je pense que les gens ici devraient remarquer à L'affiche que : Classe de nid statique seulement la première classe intérieure. 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 !!!

 }

donc, résumez, la classe statique ne dépend pas quelle classe elle contient. Donc, ils ne peuvent pas en classe normale. (parce que classe normale besoin d'un exemple).

4
répondu hqt 2013-08-21 18:10:14

quand nous déclarons la classe de membre statique à l'intérieur d'une classe, elle est connue comme la classe de haut niveau imbriquée ou une classe imbriquée statique. Il peut être démontré comme suit :

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());
    }
}

lorsque nous déclarons une classe de membre non statique à l'intérieur d'une classe, elle est connue sous le nom de classe interne. La classe intérieure peut être démontrée comme suit:

    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);
        }
    }
}
4
répondu Pankti 2016-12-02 17:00:09

exemple de static nested class et inner class :

OuterClass.java

public class OuterClass {
     private String someVariable = "Non Static";

     private static String anotherStaticVariable = "Static";  

     OuterClass(){

     }

     //Nested classes are static
     static class StaticNestedClass{
        private static String privateStaticNestedClassVariable = "Private Static Nested Class Variable"; 

        //can access private variables declared in the outer class
        public static void getPrivateVariableofOuterClass(){
            System.out.println(anotherStaticVariable);
        }
     }

     //non static
     class InnerClass{

         //can access private variables of outer class
         public String getPrivateNonStaticVariableOfOuterClass(){
             return someVariable;
         }
     }

     public static void accessStaticClass(){
         //can access any variable declared inside the Static Nested Class 
         //even if it private
         String var = OuterClass.StaticNestedClass.privateStaticNestedClassVariable; 
         System.out.println(var);
     }

}

OuterClassTest:

public class OuterClassTest {
    public static void main(String[] args) {

        //access the Static Nested Class
        OuterClass.StaticNestedClass.getPrivateVariableofOuterClass();

        //test the private variable declared inside the static nested class
        OuterClass.accessStaticClass();
        /*
         * Inner Class Test
         * */

        //Declaration

        //first instantiate the outer class
        OuterClass outerClass = new OuterClass();

        //then instantiate the inner class
        OuterClass.InnerClass innerClassExample =  outerClass. new InnerClass();

        //test the non static private variable
        System.out.println(innerClassExample.getPrivateNonStaticVariableOfOuterClass()); 

    }

}
2
répondu Pritam Banerjee 2017-01-03 23:10:14

la différence est qu'une déclaration de classe imbriquée qui est aussi statique peut être instanciée en dehors de la classe enveloppante.

lorsque vous avez une déclaration de classe imbriquée qui est et non statique, également connu comme un classe interne , Java ne vous laissera pas l'instancier sauf via la classe enclosante. L'objet créé à partir de la classe intérieure est lié à l'objet créé à partir de la classe extérieure, de sorte que la classe intérieure peut de référence les domaines de l'extérieur.

mais si c'est statique, alors le lien n'existe pas, les champs externes ne peuvent pas être accessibles (sauf via une référence ordinaire comme tout autre objet) et vous pouvez donc instancier la classe imbriquée par elle-même.

0
répondu DigitalRoss 2016-09-23 21:40:09

tout d'abord, il n'existe pas de classe appelée classe statique.Le modificateur statique utilisé avec la classe intérieure (appelé comme classe imbriquée) dit que c'est un membre statique de la classe extérieure qui signifie que nous pouvons y accéder comme avec d'autres membres statiques et sans avoir aucune instance de la classe extérieure. (Qui est l'avantage de la statique à l'origine.)

la différence entre l'utilisation de la classe imbriquée et de la classe intérieure ordinaire est:

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

d'abord nous pouvons instancier Outerclass ensuite, nous Pouvons accéder à l'Intérieur.

mais si la classe est imbriquée alors la syntaxe est:

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

qui utilise la syntaxe statique comme implémentation normale du mot-clé statique.

0
répondu Sohi 2017-06-01 19:18:01

j'ai illustré divers scénarios corrects et d'erreur possibles qui peuvent se produire dans le code java.

    class Outter1 {

        String OutStr;

        Outter1(String str) {
            OutStr = str;
        }

        public void NonStaticMethod(String st)  {

            String temp1 = "ashish";
            final String  tempFinal1 = "ashish"; 

            //  below static attribute not permitted
            // static String tempStatic1 = "static";    

            //  below static with final attribute not permitted         
            // static final String  tempStatic1 = "ashish";  

            // synchronized keyword is not permitted below          
            class localInnerNonStatic1 {            

                synchronized    public void innerMethod(String str11) {
                    str11 = temp1 +" sharma";
                    System.out.println("innerMethod ===> "+str11);
                }

                /* 
        //  static method with final not permitted
          public static void innerStaticMethod(String str11) { 

                    str11 = temp1 +" india";
                    System.out.println("innerMethod ===> "+str11);
                }*/
            }

            // static class not permitted below
            //  static class localInnerStatic1 {   }                            

        }

        public static  void StaticMethod(String st)     {

            String temp1 = "ashish";
            final String  tempFinal1 = "ashish"; 

            // static attribute not permitted below
            //static String tempStatic1 = "static";     

            //  static with final attribute not permitted below
            // static final String  tempStatic1 = "ashish";                         

            class localInnerNonStatic1 {
                public void innerMethod(String str11) {
                    str11 = temp1 +" sharma";
                    System.out.println("innerMethod ===> "+str11);
                }

                /*
    // static method with final not permitted
    public static void innerStaticMethod(String str11) {  
                    str11 = temp1 +" india";
                    System.out.println("innerMethod ===> "+str11);
                }*/
            }

            // static class not permitted below
            //  static class localInnerStatic1 {   }    

        }

        // synchronized keyword is not permitted
        static  class inner1 {          

            static String  temp1 = "ashish";
            String  tempNonStatic = "ashish";
            // class localInner1 {

            public void innerMethod(String str11) {
                str11 = temp1 +" sharma";
                str11 = str11+ tempNonStatic +" sharma";
                System.out.println("innerMethod ===> "+str11);
            }

            public static void innerStaticMethod(String str11) {
                //  error in below step
                str11 = temp1 +" india";    
                //str11 = str11+ tempNonStatic +" sharma";
                System.out.println("innerMethod ===> "+str11);
            }
            //}
        }

        //synchronized keyword is not permitted below
        class innerNonStatic1 {             

//This is important we have to keep final with static modifier in non
// static innerclass below
            static final String  temp1 = "ashish";  
            String  tempNonStatic = "ashish";
            // class localInner1 {

            synchronized    public void innerMethod(String str11) {
                tempNonStatic = tempNonStatic +" ...";
                str11 = temp1 +" sharma";
                str11 = str11+ tempNonStatic +" sharma";
                System.out.println("innerMethod ===> "+str11);
            }

            /*
            //  error in below step
            public static void innerStaticMethod(String str11) {   
                            //  error in below step
                            // str11 = tempNonStatic +" india";                     
                            str11 = temp1 +" india";
                            System.out.println("innerMethod ===> "+str11);
                        }*/
                    //}
                }
    }
0
répondu Ashish Sharma 2017-10-11 06:50:50

juste quelques ajouts après avoir lu le tutoriel java d'oracle dans classes et objets. Il peut aider si vous connaissez le modèle de mémoire de Java pour la classe intérieure et la classe statique imbriquée. Veuillez lire les trois questions suivantes pour obtenir la philosophie de pourquoi intérieure et statique de la classe imbriquée sont conçus par Java de cette façon. Et alors vous pouvez savoir quand utiliser la classe intérieure et quand utiliser la classe statique imbriquée.

Comment intérieure de la classe de l'objet réside dans la mémoire?

gestion de la mémoire - classe statique interne en Java

quand une classe statique imbriquée (et ses éléments statiques) est-elle chargée dans la mémoire?

ensuite, lisez ceci pour comparer la classe intérieure et la classe statique imbriquée.

Quel est l'avantage de rendre une classe intérieure statique avec Java?

0
répondu Han XIAO 2018-07-24 04:33:32