it-swarm-eu.dev

Classe interna Java e classe nidificata statica

Qual è la principale differenza tra una classe interna e una classe nidificata statica in Java? La progettazione/realizzazione ha un ruolo nella scelta di uno di questi?

1585
Omnipotent

Dal Java Tutorial :

Le classi annidate sono divise in due categorie: statiche e non statiche. Le classi annidate dichiarate statiche sono semplicemente chiamate classi nidificate statiche. Le classi nidificate non statiche sono chiamate classi interne. 

È possibile accedere alle classi nidificate statiche utilizzando il nome della classe che lo racchiude:

OuterClass.StaticNestedClass

Ad esempio, per creare un oggetto per la classe nidificata statica, utilizzare questa sintassi:

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

Gli oggetti che sono istanze di una classe interna esistono all'interno di un'istanza della classe esterna. Considera le seguenti classi:

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

Un'istanza di InnerClass può esistere solo all'interno di un'istanza di OuterClass e ha accesso diretto ai metodi e ai campi dell'istanza che la include.

Per creare un'istanza di una classe interiore, devi prima istanziare la classe esterna. Quindi, crea l'oggetto interno all'interno dell'oggetto esterno con questa sintassi:

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

vedi: Java Tutorial - Classi annidate

Per completezza nota che c'è anche una cosa come inner class without un'istanza allegata :

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

Qui, new A() { ... } è una inner class definita in un contesto statico e non ha un'istanza di inclusione.

1564
Martin

Non penso che la vera differenza sia diventata chiara nelle risposte di cui sopra. 

Innanzitutto per ottenere i termini giusti: 

  • Una classe nidificata è una classe che è contenuta in un'altra classe a livello di codice sorgente.
  • È statico se lo dichiari con il modificatore static .
  • Una classe nidificata non statica è chiamata classe interna. (Rimango con una classe annidata non statica).

La risposta di Martin è giusta finora. Tuttavia, la vera domanda è: qual è lo scopo di dichiarare una classe nidificata statica o no?

Si utilizzano classi statiche nidificate se si desidera mantenere le classi insieme se appartengono topicamente insieme o se la classe nidificata viene utilizzata esclusivamente nella classe che la include. Non c'è alcuna differenza semantica tra una classe nidificata statica e ogni altra classe.

Classi annidate non statiche sono una bestia diversa. Simile alle classi interne anonime, tali classi annidate sono in realtà delle chiusure. Ciò significa che acquisiscono il loro ambito circostante e la loro istanza che lo racchiude e lo rendono accessibile. Forse un esempio lo chiarirà. Vedi questo mozzicone di un contenitore:

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

In questo caso si desidera avere un riferimento da un elemento figlio al contenitore padre. Usando una classe nidificata non statica, questo funziona senza alcuno sforzo. È possibile accedere all'istanza di Container allegata con la sintassi Container.this.

Spiegazioni più approfondite seguenti:

Se si guardano i bytecode Java che il compilatore genera per una classe nidificata (non statica), potrebbe diventare ancora più chiaro:

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

Come puoi vedere il compilatore crea un campo nascosto Container this$0. Questo è impostato nel costruttore che ha un parametro aggiuntivo di tipo Container per specificare l'istanza allegata. Non è possibile visualizzare questo parametro nel codice sorgente ma il compilatore lo genera implicitamente per una classe nidificata. 

L'esempio di Martin

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

sarebbe così compilato per una chiamata di qualcosa di simile (in bytecodes)

new InnerClass(outerObject)

Per amor di completezza:

Una classe anonima è un perfetto esempio di una classe nidificata non statica che non ha alcun nome associato ad essa e non può essere referenziata in seguito.

131
jrudolph

Penso che nessuna delle risposte precedenti spieghi la vera differenza tra una classe nidificata e una classe nidificata statica in termini di design dell'applicazione: 

OverView

Una classe nidificata potrebbe essere non statica o statica e in ogni caso è una classe definita all'interno di un'altra classe . Una classe nidificata dovrebbe esistere solo per servire è racchiudere la classe , se una classe nidificata è utile per altre classi (non solo l'inclusione), dovrebbe essere dichiarata come una classe di livello superiore.

Differenza

La classe Nested nonstatica : è implicitamente associata all'istanza che la racchiude nella classe contenitore, ciò significa che è possibile richiamare metodi e accedere alle variabili dell'istanza acclusa. Un uso comune di una classe nidificata nonstatica è definire una classe Adapter.

La classe nidificata statica : non può accedere all'istanza della classe che racchiude e invocare metodi su di essa, quindi dovrebbe essere utilizzata quando la classe nidificata non richiede l'accesso a un'istanza della classe che la include. Un uso comune della classe nidificata statica consiste nell'implementare un componente dell'oggetto esterno.

Conclusione

Quindi la principale differenza tra i due dal punto di vista del design è la seguente: la classe nidificata nonstatica può accedere all'istanza della classe contenitore, mentre static non può.

88
aleroot

In termini semplici, abbiamo bisogno di classi nidificate principalmente perché Java non fornisce chiusure.

Le classi annidate sono classi definite all'interno del corpo di un'altra classe che racchiude. Sono di due tipi: statici e non statici.

Vengono considerati membri della classe che li include, quindi è possibile specificare uno dei quattro specificatori di accesso: private, package, protected, public. Non abbiamo questo lusso con le classi di primo livello, che possono essere dichiarate solo public o package-private.

Classi interne alias Le classi non stack hanno accesso ad altri membri della classe superiore, anche se sono dichiarate private mentre le classi nidificate statiche non hanno accesso ad altri membri della classe superiore.

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

Inner1 è la nostra classe interna statica e Inner2 è la nostra classe interna che non è statica. La differenza fondamentale tra di loro, non è possibile creare un'istanza Inner2 senza un Outer in cui è possibile creare indipendentemente un oggetto Inner1.

Quando useresti la classe Inner?

Pensa a una situazione in cui Class A e Class B sono correlati, Class B deve accedere ai membri Class A e Class B è relativo solo a Class A. Le classi interne entrano in scena.

Per creare un'istanza di inner class, devi creare un'istanza della tua classe esterna.

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

o

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

Quando useresti la classe Inner static?

Definiresti una classe interna statica quando saprai che non ha alcuna relazione con l'istanza della classe/classe superiore che la racchiude. Se la tua classe interiore non usa metodi o campi della classe esterna, è solo uno spreco di spazio, quindi rendilo statico.

Ad esempio, per creare un oggetto per la classe nidificata statica, utilizzare questa sintassi:

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

Il vantaggio di una classe nidificata statica è che non ha bisogno di un oggetto della classe contenente/classe superiore per funzionare. Questo può aiutarti a ridurre il numero di oggetti creati dall'applicazione in fase di runtime.

31
Thalaivar

Penso che la convenzione generalmente seguita sia questa:

  • La classe statica all'interno di una classe di livello superiore è una classe nidificata
  • classe non statica all'interno di una classe di livello superiore è una classe interna , che ulteriormente ha un'altra forma:
    • classe locale - classi denominate dichiarate all'interno di un blocco come un metodo o un corpo costruttore
    • classe anonima - classi senza nome le cui istanze sono create in espressioni e istruzioni

Tuttavia, pochi altri punti da ricordare sono:

  • Le classi di livello superiore e le classi nidificate statiche sono semanticamente uguali, tranne che nel caso di classi nidificate statiche può fare riferimento statico a campi/metodi statici privati ​​della sua classe Outer [parent] e viceversa.

  • Le classi interne hanno accesso alle variabili di istanza dell'istanza allegata della classe Outer [genitore]. Tuttavia, non tutte le classi interne hanno istanze che racchiudono, per esempio classi interne in contesti statici, come una classe anonima usata in un blocco di inizializzazione statico, no.

  • La classe anonima per impostazione predefinita estende la classe genitore o implementa l'interfaccia genitore e non ci sono ulteriori clausole per estendere qualsiasi altra classe o implementare altre interfacce. Così,

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

Sento che la domanda più grande che rimane aperta quale usare e quando? Beh, questo dipende in gran parte da quale scenario hai a che fare, ma leggere la risposta fornita da @jrudolph può aiutarti a prendere una decisione.

26
sactiw

Ecco le principali differenze e somiglianze tra la classe interna Java e la classe nidificata statica.

Spero che sia d'aiuto!

Classe interiore

  • Può accedere ai campi e alla classe esterna both instance e static
  • Associata con l'istanza della classe di inclusione in modo da creare un'istanza per prima cosa ha bisogno di un'istanza di classe esterna (nota nuova posizione della parola chiave):

    Outerclass.InnerClass innerObject = outerObject.new Innerclass();
    
  • Can not definisce static membri stesso

  • Can not have Class or Interface declaration

Classe nidificata statica

  • Impossibile accedere ai metodi o campi della classe esterna instance

  • Non associato a nessuna istanza di classe di inclusione Quindi per istanziarlo:

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

Analogie

  • Entrambe le classi Inner possono accedere anche ai campi private e ai metodi di outer class
  • Anche la Outer class ha accesso a private fields and methods of inner classes
  • Entrambe le classi possono avere un modificatore privato, protetto o di accesso pubblico

Perché usare le classi annidate?

Secondo la documentazione di Oracle ci sono diversi motivi ( documentazione completa ):

  • È un modo di raggruppare logicamente le classi che vengono utilizzate solo in un posto: Se una classe è utile solo per un'altra classe, è logico incorporarla in quella classe e mantenerla insieme. Annidare tali "classi di supporto" rende il loro pacchetto più snello.

  • Aumenta l'incapsulamento: Considera due classi di primo livello, A e B, dove B ha bisogno di accedere ai membri di A che altrimenti sarebbero dichiarati privati. Nascondendo la classe B all'interno della classe A, i membri di A possono essere dichiarati privati ​​e B può accedervi. Inoltre, la stessa B può essere nascosta dal mondo esterno.

  • Può portare a un codice più leggibile e gestibile: L'annidamento di classi piccole all'interno delle classi di livello superiore avvicina il codice a dove viene utilizzato.

26
Behzad Bahmanyar

Classe annidata: classe in classe

Tipi:

  1. Classe nidificata statica
  2. Classe annidata non statica [Classe interna]

Differenza:

Classe annidata non statica [Classe interna]

Nell'oggetto di classe nidificato non statico della classe interna esiste all'interno dell'oggetto della classe esterna. In modo che il membro dei dati della classe esterna sia accessibile alla classe interna. Quindi per creare l'oggetto della classe interiore dobbiamo prima creare l'oggetto della classe esterna.

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

Classe annidata statica

Nell'oggetto di classe nidificato statico della classe interna non è necessario l'oggetto della classe esterna, poiché la parola "statico" non indica la necessità di creare oggetti.

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

Se si desidera accedere a x, quindi scrivere il seguente metodo interno

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

Esiste una sottigliezza sull'uso di classi statiche nidificate che potrebbero essere utili in determinate situazioni.

Mentre gli attributi statici vengono istanziati prima che la classe venga istanziata tramite il suo costruttore, gli attributi statici all'interno delle classi statiche nidificate non sembrano essere istanziati fino a quando il costruttore della classe Non viene richiamato, o almeno non fino a dopo gli attributi vengono prima referenziati, anche se sono contrassegnati come "finali".

Considera questo esempio:

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

Anche se "nested" e "innerItem" sono entrambi dichiarati come "static final". l'impostazione di nested.innerItem non ha luogo fino a dopo la creazione dell'istanza della classe (o almeno non fino a dopo il riferimento dell'elemento statico nidificato), come si può vedere da soli. e decommentando le linee a cui mi riferisco, sopra. Lo stesso non vale True per 'outerItem'.

Almeno questo è quello che vedo in Java 6.0.

11
HippoMan

L'istanza della classe interna viene creata quando viene creata l'istanza della classe esterna. Pertanto membri e metodi della classe interna hanno accesso ai membri e ai metodi dell'istanza (oggetto) della classe esterna. Quando l'istanza della classe esterna esce dall'ambito, anche le istanze della classe interna cessano di esistere.

La classe nidificata statica non ha un'istanza concreta. È appena caricato quando viene usato per la prima volta (proprio come i metodi statici). È un'entità completamente indipendente, i cui metodi e variabili non hanno accesso alle istanze della classe esterna.

Le classi nidificate statiche non sono accoppiate con l'oggetto esterno, sono più veloci e non prendono la memoria heap/stack, perché non è necessario creare un'istanza di tale classe. Quindi la regola generale è cercare di definire una classe nidificata statica, con un ambito il più limitato possibile (privato> = classe> = protetto> = pubblico), quindi convertirla in classe interna (rimuovendo l'identificatore "statico") e allentare lo scopo, se è davvero necessario.

11
rmaruszewski

Non penso che ci sia molto da aggiungere qui, la maggior parte delle risposte spiega perfettamente le differenze tra classi nidificate statiche e classi interne. Tuttavia, si consideri il seguente problema quando si utilizzano classi nidificate e classi interne. Come menzionato in un paio di risposte, le classi interne non possono essere istanziate senza ed istanza della loro classe che le racchiude, il che significa che esseTENGONOa puntatore all'istanza della loro classe di chiusura che può condurre all'eccezione di overflow di memoria o di overflow dello stack a causa del fatto che il GC non sarà in grado di raccogliere le classi che lo contengono, anche se non vengono più utilizzate. Per chiarire questo, controlla il seguente codice: 

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

}

Se rimuovi il commento su // inner = null; il programma verrà messo fuori " I am destroyed! ", ma mantenendo questo commento non lo farà.
Il motivo è che l'istanza interna bianca è ancora referenziata. GC non può raccoglierla e perché fa riferimento (ha un puntatore a) all'istanza esterna che non viene raccolta. Avere abbastanza di questi oggetti nel progetto e può esaurire la memoria.
Confronto con le classi interne statiche che non contengono un punto per l'istanza della classe interna perché non è correlata all'istanza ma alla classe. Il programma di cui sopra può stampare " I am destroyed! " se si rende la classe Inner statica e istanziata con Outer.Inner i = new Outer.Inner(); 

10
Adelin

Nel caso della creazione di un'istanza, l'istanza della classe interna non Static viene creata con il riferimento dell'oggetto Della classe esterna in cui è definita. Questo Significa che ha inclusione dell'istanza . Ma l'istanza di static interna classè creata con il riferimento della classe Outer, non con Il riferimento dell'oggetto della classe esterna. Questo significa che Non ha inclusivo di istanza.

Per esempio:

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….
  }
}
10
Ankit Jain

I termini sono usati in modo intercambiabile. Se vuoi essere veramente pedante al riguardo, allora potrebbe definire "classe nidificata" per riferirsi a una classe interna statica, una che non ha istanze che lo racchiudono. Nel codice, potresti avere qualcosa di simile a questo:

public class Outer {
    public class Inner {}

    public static class Nested {}
}

Questa però non è una definizione ampiamente accettata.

8
Daniel Spiewak

La classe nidificata è un termine molto generale: ogni classe che non è di primo livello è una classe nidificata . Una classe interiore è una classe nidificata non statica . Joseph Darcy ha scritto una spiegazione molto bella su Nested, Inner , Membro e Classi di primo livello .

8
Wouter Coekaerts

Studente di targeting, che è alle prime armi di Java e/o classi annidate 

Le classi annidate possono essere:
1. Classi annidate statiche.
2. Classi annidate non statiche. (noto anche come Inner classes) => Per favore, ricorda questo


1. Classi interne
Esempio:

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


Le classi interne sono sottoinsiemi di classi annidate:

  • la classe interna è un tipo specifico di classe nidificata
  • le classi interne sono sottoinsiemi di classi annidate
  • Puoi dire che una inner class è anche una classe nidificata, ma puoi NOT dire che una classe nidificata è anche una classe interna

Specialità della classe Inner:

  • l'istanza di una classe interna ha accesso a tutti dei membri della classe esterna, anche quelli che sono contrassegnati come "privati"


2. Classi annidate statiche:
Esempio:

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

Caso 1: istanziazione di una classe nidificata statica da una classe non inclusa

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

Caso 2: istanziazione di una classe nidificata statica da una classe che include

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

}

Specialità delle classi statiche:

  • La classe interna statica ha solo accesso ai membri statici della classe esterna e non ha accesso ai membri non statici.

Conclusione:
Domanda: Qual è la principale differenza tra una classe interna e una classe nidificata statica in Java?
Answer: vai solo attraverso le specifiche di ogni classe sopra menzionata.

7
VdeX

Ummm ... una classe interiore IS una classe nidificata ... intendi classe anonima e classe interiore?

Modifica: se in realtà intendevi interiore vs anonimo ... una classe interiore è solo una classe definita all'interno di una classe come:

public class A {
    public class B {
    }
}

Mentre una classe anonima è un'estensione di una classe definita in modo anonimo, quindi nessuna "classe" viene definita, come in:

public class A {
}

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

Ulteriori modifica:

Wikipedia afferma che c'è una differenza in Java, ma ho lavorato con Java per 8 anni, ed è il primo che ho sentito una distinzione del genere ... per non parlare del fatto che non ci sono riferimenti per il backup del reclamo ... linea di fondo, una classe interna è una classe definita all'interno di una classe (statica o meno) e nidificata è solo un altro termine per indicare la stessa cosa.

C'è una sottile differenza tra la classe nidificata statica e quella non statica ... le classi interne fondamentalmente non statiche hanno accesso implicito ai campi di istanza e ai metodi della classe che li racchiude (quindi non possono essere costruiti in un contesto statico, sarà un compilatore errore). Le classi nidificate statiche, d'altra parte, non hanno accesso implicito ai campi e ai metodi dell'istanza e possono essere costruite in un contesto statico.

7
Mike Stone

Classe interna e classe nidificata nidificata in Java entrambe sono classi dichiarate all'interno di un'altra classe, nota come classe di primo livello in Java. Nella terminologia Java, se dichiari una classe nidificata statica, chiamerà la classe statica nidificata in Java mentre la classe nidificata non statica viene semplicemente chiamata Classe interna. 

Che cos'è Inner Class in Java?

Qualsiasi classe che non è un livello superiore o dichiarata all'interno di un'altra classe è conosciuta come classe nidificata e da quelle classi nidificate, la classe che è dichiarata non statica è nota come classe Inner in Java. ci sono tre tipi di classi interne in Java:

1) Classe interna locale - è dichiarata all'interno di un blocco di codice o metodo.
2) Anonimo inner class - è una classe che non ha un nome da referenziare e inizializzare nello stesso punto in cui viene creata.
3) La classe interna del membro - è dichiarata come membro non statico della classe esterna.

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

Cos'è la classe statica nidificata in Java?

La classe statica annidata è un'altra classe dichiarata all'interno di una classe come membro e resa statica. La classe statica nidificata viene anche dichiarata come membro di una classe esterna e può essere privata, pubblica o protetta come qualsiasi altro membro. Uno dei principali vantaggi della classe statica nidificata rispetto alla classe interna è che l'istanza della classe statica nidificata non è collegata a nessuna istanza che racchiude la classe Outer. Non è inoltre necessaria alcuna istanza della classe Outer per creare un'istanza di classe statica nidificata in Java.

1) Può accedere a membri statici dei dati di classe esterna incluso privato.
2) La classe nidificata statica non può accedere a membro dati non statico (istanza) o metodo.

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

Rif: Classe interna e classe statica nidificata in Java con Esempio

6
roottraveller

Quando dichiariamo una classe membro statica all'interno di una classe, è conosciuta come classe nidificata di primo livello o classe nidificata statica. Può essere dimostrato come di seguito: 

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

Quando dichiariamo una classe membro non statica all'interno di una classe è conosciuta come classe interna. La classe interiore può essere dimostrata come segue: 

    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);
        }
    }
}
5
Pankti

Penso che le persone qui dovrebbero notare che Poster: Static Nest Class solo solo la prima classe interna . Ad esempio:

 public static class A {} //ERROR

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

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

 }

Quindi, riepilogare, la classe statica non dipende da quale classe è contenuta. Quindi, non possono nella classe normale. (perché la classe normale ha bisogno di un'istanza).

5
hqt

Quello che segue è un esempio di static nested class e 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()); 

    }

}
3
Pritam Banerjee

Penso che nessuna delle risposte precedenti dia il vero esempio della differenza tra una classe nidificata e una classe nidificata statica in termini di design dell'applicazione. E la differenza principale tra la classe nidificata statica e la classe interna è la possibilità di accedere al campo dell'istanza di classe esterna.

Diamo un'occhiata ai due esempi seguenti.

Classe di nido statico: un buon esempio di utilizzo di classi nidificate statiche è il modello di builder ( https://dzone.com/articles/design-patterns-the-builder-pattern ).

Per BankAccount usiamo una classe nidificata statica, principalmente perché

  1. L'istanza della classe nest statica potrebbe essere creata prima della classe esterna.

  2. Nel modello di builder, il builder è una classe helper che viene utilizzata per creare BankAccount.

  3. BankAccount.Builder è associato solo a BankAccount. Nessun'altra classe è collegata a BankAccount.Builder. quindi è meglio organizzarli insieme senza usare la convenzione dei nomi.
public class BankAccount {

    private long accountNumber;
    private String owner;
    ...

    public static class Builder {

    private long accountNumber;
    private String owner;
    ...

    static public Builder(long accountNumber) {
        this.accountNumber = accountNumber;
    }

    public Builder withOwner(String owner){
        this.owner = owner;
        return this; 
    }

    ...
    public BankAccount build(){
            BankAccount account = new BankAccount(); 
            account.accountNumber = this.accountNumber;
            account.owner = this.owner;
            ...
            return account;
        }
    }
}

Classe interna: un uso comune delle classi interne consiste nel definire un gestore di eventi. https://docs.Oracle.com/javase/tutorial/uiswing/events/generalrules.html

Per MyClass, usiamo la classe interna, principalmente perché:

  1. La classe interna MyAdapter deve accedere al membro della classe esterna.

  2. Nell'esempio, MyAdapter è associato solo a MyClass. Nessuna altra classe è correlata a MyAdapter. quindi è meglio organizzarli insieme senza usare una convenzione sui nomi

public class MyClass extends Applet {
    ...
        someObject.addMouseListener(new MyAdapter());
    ...
    class MyAdapter extends MouseAdapter {
        public void mouseClicked(MouseEvent e) {
            ...// Event listener implementation goes here...
            ...// change some outer class instance property depend on the event
        }
    }
}
1
Leogao

Il linguaggio di programmazione Java consente di definire una classe all'interno di un'altra classe. Tale classe è chiamata classe nidificata ed è qui illustrata:

class OuterClass {
...
class NestedClass {
    ...
    }
}

Le classi annidate sono divise in due categorie: statiche e non statiche. Le classi nidificate dichiarate statiche sono chiamate classi nidificate statiche. Le classi nidificate non statiche sono chiamate classi interne. Una cosa che dovremmo tenere a mente è che le classi nidificate non statiche (classi interne) hanno accesso ad altri membri della classe che li include, anche se sono dichiarate private. Le classi nidificate statiche hanno solo accesso ad altri membri della classe che racchiude se sono statiche. Non può accedere ai membri non statici della classe esterna . Come con i metodi e le variabili di classe, una classe nidificata statica è associata alla sua classe esterna. Ad esempio, per creare un oggetto per la classe nidificata statica, utilizzare questa sintassi:

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

Per creare un'istanza di una classe interiore, devi prima istanziare la classe esterna. Quindi, crea l'oggetto interno all'interno dell'oggetto esterno con questa sintassi:

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

Perché usiamo le classi annidate

  1. È un modo di raggruppare logicamente le classi che vengono utilizzate solo in un posto.
  2. Aumenta l'incapsulamento.
  3. Può portare a un codice più leggibile e gestibile.

Fonte: Le esercitazioni Java ™ - Classi nidificate

0
Mithun Debnath

Prima di tutto Non esiste una classe chiamata Classica. Il modificatore statico usa con la classe interna (chiamata classe Nested) dice che è un membro statico di Outer Class, il che significa che possiamo accedervi come con altri membri statici e senza averne istanza di classe Outer. (Che è il vantaggio di statico in origine.) 

La differenza tra l'uso della classe annidata e della classe interna normale è:

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

Per prima cosa possiamo creare un'istanza di Outerclass, quindi possiamo accedere a Inner.

Ma se la classe è annidata, la sintassi è:

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

Che utilizza la sintassi statica come normale implementazione della parola chiave statica.

0
Sohi