Classe interna Java e classe nidificata statica


1766

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


65
La risposta di Joshua Bloch è nella lettura di Java efficaceitem 22 : Favor static member classes over non static
Raymond Chenon,

4
Per la cronaca, è l'articolo 24 della 3a edizione dello stesso libro.
ZeroCool

Risposte:


1697

Dal tutorial Java :

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

Alle classi nidificate statiche si accede utilizzando il nome della classe allegato:

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 racchiude.

Per creare un'istanza di una classe interna, è innanzitutto necessario creare un'istanza della classe esterna. Quindi, crea l'oggetto interno all'interno dell'oggetto esterno con questa sintassi:

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

vedi: Tutorial Java - Classi nidificate

Per completezza notare che esiste anche qualcosa come una classe interna senza un'istanza chiusa :

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

Qui, new A() { ... }è una classe interna definita in un contesto statico e non ha un'istanza chiusa.


130
Ricordate che è anche possibile importare direttamente una classe innestata statica, cioè si potrebbe fare (nella parte superiore del file): import OuterClass.StaticNestedClass; quindi riferimento alla classe proprio come OuterClass.
Camilo Díaz Repka,

4
@Martin c'è un nome tecnico specifico per questo idioma della creazione di una classe interna OuterClass.InnerClass innerObject = outerObject.new InnerClass();?
Geek,

7
Allora, a che serve la classe annidata statica privata? Penso che non possiamo istanziarlo da fuori come OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass ();
RoboAlex,

1
@Ilya Kogan: volevo dire che so che possiamo accedere ai campi di classe dei genitori statici o non statici (se la classe figlio è una classe non statica) ho usato le loro caratteristiche un paio di volte, ma mi chiedevo che tipo di modello di memoria seguono? i concetti di OOP li coprono come un concetto separato? se non dove si inseriscono davvero all'interno di OOP. Mi sembra una classe di amici :)
Mubashar,

4
@martin, so che sto arrivando a questa discussione incredibilmente tardi ma: è la tua variabile, a, che è un campo statico della classe, A. Ciò non significa che la classe anonima creata da 'new A () {int t () {ritorno 2; }} 'non è più statico che se semplicemente assegnassi qualsiasi altro oggetto al campo statico, a, come in: class B {void statico principale (stringhe) {Aa = new A ()}} (A & B nella stessa pacchetto) Questo non rende A una classe statica. La frase "contesto statico", nel riferimento citato nel thread a cui ti sei collegato, è incredibilmente vaga. In effetti, questo è stato notato in molti dei commenti in quella discussione.
GrantRobertson,

599

Il tutorial Java dice :

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

Nel linguaggio comune, i termini "nidificato" e "interno" sono usati in modo intercambiabile dalla maggior parte dei programmatori, ma userò il termine corretto "classe nidificata" che copre sia interno che statico.

Le classi possono essere nidificate all'infinito , ad es. La classe A può contenere la classe B che contiene la classe C che contiene la classe D, ecc. Tuttavia, più di un livello di annidamento delle classi è raro, poiché generalmente è un progetto errato.

Esistono tre motivi per cui potresti creare una classe nidificata:

  • organizzazione: a volte sembra più sensato ordinare una classe nello spazio dei nomi di un'altra classe, specialmente quando non verrà utilizzata in nessun altro contesto
  • accesso: le classi nidificate hanno un accesso speciale alle variabili / ai campi delle loro classi di contenimento (precisamente quali variabili / campi dipendono dal tipo di classe nidificata, sia interna che statica).
  • convenienza: dover creare un nuovo file per ogni nuovo tipo è di nuovo fastidioso, soprattutto quando il tipo verrà utilizzato solo in un contesto

Esistono quattro tipi di classe nidificata in Java . In breve, sono:

  • classe statica : dichiarata come membro statico di un'altra classe
  • classe interna : dichiarata come membro di istanza di un'altra classe
  • classe interna locale : dichiarata all'interno di un metodo di istanza di un'altra classe
  • classe interna anonima : come una classe interna locale, ma scritta come espressione che restituisce un oggetto unico

Permettetemi di elaborare in modo più dettagliato.


Classi statiche

Le classi statiche sono il tipo più semplice da comprendere perché non hanno nulla a che fare con le istanze della classe contenente.

Una classe statica è una classe dichiarata come membro statico di un'altra classe. Proprio come gli altri membri statici, una classe di questo tipo è in realtà solo un appendiabiti che utilizza la classe contenitore come suo spazio dei nomi, ad esempio la classe Goat dichiarata come membro statico della classe Rhino nel pacchetto pizza è conosciuta con il nome pizza.Rhino.Goat .

package pizza;

public class Rhino {

    ...

    public static class Goat {
        ...
    }
}

Francamente, le classi statiche sono una caratteristica piuttosto inutile perché le classi sono già divise in spazi dei nomi dai pacchetti. L'unico vero motivo immaginabile per creare una classe statica è che una tale classe ha accesso ai membri statici privati ​​della sua classe contenente, ma trovo che questa sia una giustificazione piuttosto scadente per l'esistenza della funzione di classe statica.


Classi interne

Una classe interna è una classe dichiarata come membro non statico di un'altra classe:

package pizza;

public class Rhino {

    public class Goat {
        ...
    }

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

Come con una classe statica, la classe interna è conosciuta come qualificata dal suo nome di classe contenente, pizza.Rhino.Goat , ma all'interno della classe di contenimento, può essere conosciuta con il suo nome semplice. Tuttavia, ogni esempio di una classe interna è legato ad una determinata condizione di classe contenente: sopra, la capra creato in Jerry , è implicitamente legata alla Rhino esempio questo in Jerry . Altrimenti, rendiamo esplicita l'istanza di Rhino associata quando istanziamo Goat :

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

(Nota che ti riferisci al tipo interno come solo Capra nella strana nuova sintassi: Java deduce il tipo contenitivo dalla parte del rinoceronte . E sì, il nuovo rhino.Goat () avrebbe avuto più senso anche per me.)

Cosa ci guadagna questo? Bene, l'istanza di classe interna ha accesso ai membri di istanza dell'istanza di classe contenente. Questi membri dell'istanza che li racchiudono vengono citati all'interno della classe interna solo tramite i loro nomi semplici, non tramite questo ( ciò nella classe interna si riferisce all'istanza della classe interna, non all'istanza della classe contenente associata):

public class Rhino {

    private String barry;

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

Nella classe interna, è possibile fare riferimento a questo della classe contenente come Rhino.this , ed è possibile utilizzare questo per fare riferimento ai suoi membri, ad esempio Rhino.this.barry .


Classi interne locali

Una classe interna locale è una classe dichiarata nel corpo di un metodo. Tale classe è nota solo nel suo metodo di contenimento, quindi può solo essere istanziata e avere accesso ai suoi membri nel suo metodo di contenimento. Il vantaggio è che un'istanza di classe interna locale è collegata e può accedere alle variabili locali finali del suo metodo di contenimento. Quando l'istanza utilizza un locale finale del suo metodo di contenimento, la variabile conserva il valore che deteneva al momento della creazione dell'istanza, anche se la variabile è andata fuori dal campo di applicazione (si tratta effettivamente della versione grezza e limitata di chiusure di Java).

Poiché una classe interna locale non è né membro di una classe o pacchetto, non viene dichiarata con un livello di accesso. (Sii chiaro, tuttavia, che i suoi membri hanno livelli di accesso come in una classe normale.)

Se una classe interna locale viene dichiarata in un metodo di istanza, un'istanza della classe interna è legata all'istanza detenuta dal metodo contenitore presente al momento della creazione dell'istanza, e quindi i membri dell'istanza della classe contenitore sono accessibili come in un'istanza classe interiore. Una classe interna locale viene istanziata semplicemente tramite il suo nome, ad esempio la classe interna locale Cat viene istanziata come nuovo Cat () , non nuovo this.Cat () come ci si potrebbe aspettare.


Classi interne anonime

Una classe interna anonima è un modo sintatticamente conveniente di scrivere una classe interna locale. Più comunemente, una classe interna locale viene istanziata al massimo una volta ogni volta che viene eseguito il suo metodo di contenimento. Sarebbe bello, quindi, se potessimo combinare la definizione di classe interna locale e la sua singola istanza in una comoda forma di sintassi, e sarebbe anche bello se non dovessimo pensare a un nome per la classe (meno inutili nomi contenuti nel codice, meglio è). Una classe interna anonima consente entrambe queste cose:

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

Questa è un'espressione che restituisce una nuova istanza di una classe senza nome che estende ParentClassName . Non puoi fornire il tuo costruttore; piuttosto, ne viene fornito uno implicitamente che chiama semplicemente il super costruttore, quindi gli argomenti forniti devono adattarsi al super costruttore. (Se il genitore contiene più costruttori, viene chiamato quello "più semplice", "più semplice" come determinato da un insieme piuttosto complesso di regole che non vale la pena di imparare in dettaglio - presta attenzione a ciò che NetBeans o Eclipse ti dicono.)

In alternativa, puoi specificare un'interfaccia per implementare:

new *InterfaceName*() {*members*}

Tale dichiarazione crea una nuova istanza di una classe senza nome che estende Object e implementa InterfaceName . Ancora una volta, non è possibile fornire il proprio costruttore; in questo caso, Java fornisce implicitamente un costruttore no-arg, do-nothing (quindi non ci saranno mai argomenti di costruzione in questo caso).

Anche se non è possibile assegnare a una classe interna anonima un costruttore, è comunque possibile eseguire qualsiasi impostazione desiderata utilizzando un blocco di inizializzazione (un blocco {} posizionato al di fuori di qualsiasi metodo).

Sii chiaro che una classe interna anonima è semplicemente un modo meno flessibile di creare una classe interna locale con un'istanza. Se si desidera una classe interna locale che implementa più interfacce o che implementa interfacce estendendo una classe diversa da Object o che specifica il proprio costruttore, si è bloccati nel creare una classe interna locale denominata regolare.


39
Grande storia, grazie. Ha un errore però. Puoi accedere ai campi di una classe esterna da una classe interna di istanza di Rhino.this.variableName.
Thirler,

2
Sebbene non sia possibile fornire il proprio costruttore per classi interne anonime, è possibile utilizzare l'inizializzazione con doppio controvento. c2.com/cgi/wiki?DoubleBraceInitialization
Casebash

30
Grande spiegazione, ma non sono d'accordo sul fatto che le classi interne statiche siano prive di valore. Vedi rwhansen.blogspot.com/2007/07/… per una grande variazione del modello del builder che dipende fortemente dall'uso di classi interne statiche.
Mansoor Siddiqui,

9
Non sono inoltre d'accordo sul fatto che la classe interna statica sia inutile: se vuoi un enum nella classe interna, dovrai rendere statica la classe interna.
Someone Somewhere,

9
Anche le classi nidificate statiche private sono abbastanza utili: vuoi averle, ma non vuoi esporle. Come Entry <T> in un LinkedList <T> o AsyncTasks all'interno di un'attività (Android), ecc ...
Lorenzo Dematté,

150

Non credo che la vera differenza sia diventata chiara nelle risposte sopra.

Prima di 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 statico .
  • Una classe nidificata non statica è chiamata classe interna. (Rimango con classe nidificata non statica.)

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

Si utilizzano classi nidificate statiche se si desidera solo mantenere le classi insieme se appartengono per via topica insieme o se la classe nidificata viene utilizzata esclusivamente nella classe che la racchiude. Non esiste alcuna differenza semantica tra una classe nidificata statica e ogni altra classe.

Le classi nidificate non statiche sono una bestia diversa. Simile alle classi interne anonime, tali classi nidificate sono in realtà 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 troncone 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. Utilizzando una classe nidificata non statica, questo funziona senza alcun lavoro. È possibile accedere all'istanza inclusa di Container con la sintassi Container.this.

Altre spiegazioni hardcore seguenti:

Se guardi i bytecode Java generati dal compilatore 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 Contenitore per specificare l'istanza che la contiene. Non è possibile visualizzare questo parametro nell'origine ma il compilatore lo genera implicitamente per una classe nidificata.

L'esempio di Martin

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

verrebbe quindi compilato per una chiamata di qualcosa di simile (in bytecodes)

new InnerClass(outerObject)

Per amor di completezza:

Una classe anonima è un esempio perfetto di una classe nidificata non statica a cui non è associato alcun nome e alla quale non è possibile fare riferimento in un secondo momento.


17
"Non esiste alcuna differenza semantica tra una classe nidificata statica e ogni altra classe." Tranne che la classe nidificata può vedere i campi / metodi privati ​​del genitore e la classe genitore può vedere i campi / metodi privati ​​del nidificato.
Brad Cupit,

La classe interna non statica non causerebbe potenzialmente enormi perdite di memoria? Come in, ogni volta che crei un ascoltatore, crei una perdita?
G_V,

3
@G_V c'è sicuramente il potenziale per perdite di memoria perché un'istanza della classe interna mantiene un riferimento alla classe esterna. Se questo è un problema reale dipende da dove e come vengono conservati i riferimenti alle istanze delle classi esterna e interna.
jrudolph,

94

Penso che nessuna delle risposte sopra ti spieghi la vera differenza tra una classe nidificata e una classe annidata statica in termini di progettazione dell'applicazione:

OverView

Una classe nidificata può 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 è la classe che racchiude , se una classe nidificata è utile per altre classi (non solo quella che lo racchiude), dovrebbe essere dichiarata come classe di livello superiore.

Differenza

Classe nidificata non statica : è implicitamente associata all'istanza che racchiude la classe contenente, ciò significa che è possibile invocare metodi e accedere alle variabili dell'istanza che lo racchiude. Un uso comune di una classe nidificata non statica è la definizione di una classe Adapter.

Classe nidificata statica : impossibile accedere all'istanza di classe racchiusa e invocare metodi su di essa, pertanto deve essere utilizzata quando la classe nidificata non richiede l'accesso a un'istanza della classe che la racchiude. Un uso comune della classe nidificata statica consiste nell'implementare un componente dell'oggetto esterno.

Conclusione

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


: dalla tua conclusione "mentre statico non può", nemmeno istanze statiche del contenitore? Sicuro?
VdeX,

Un uso comune della classe nidificata statica è il modello di progettazione ViewHolder in RecyclerView ed ListView.
Hamzeh Soboh,

1
In molti casi, la risposta breve è più chiara e migliore. Questo è un esempio.
Eric Wang

32

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

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

Sono trattati come membri della classe che lo racchiude, quindi è possibile specificare uno dei quattro identificatori di accesso - private, package, protected, public. Non abbiamo questo lusso con classi di alto livello, che possono solo essere dichiarate publico riservate al pacchetto.

Le classi interne ovvero 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 ed Inner2è la nostra classe interna che non è statica. La differenza fondamentale tra loro, non è possibile creare Inner2un'istanza senza un esterno in cui è possibile creare un Inner1oggetto in modo indipendente.

Quando useresti la classe interna?

Pensa a una situazione in cui Class Ae Class Bsono collegati, Class Bdeve accedere ai Class Amembri ed Class Bè legato solo a Class A. Classi interiori entrano in scena.

Per creare un'istanza della classe interna, è necessario creare un'istanza della classe esterna.

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

o

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

Quando useresti la classe interna statica?

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

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 / classe superiore contenente per funzionare. Questo può aiutarti a ridurre il numero di oggetti creati dalla tua applicazione in fase di esecuzione.


3
intendevi OuterClass.Inner2 inner = outer.new Inner2();?
Erik Kaplun,

4
static innerè una contraddizione in termini.
Marchese di Lorne,

E le classi interne non sono anche conosciute come "classi non stack". Non usare la formattazione del codice per il testo che non è codice e non lo usi per il testo che lo è.
Marchese di Lorne,

30

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

Spero che sia d'aiuto!

Classe interna

  • Può accedere alla classe esterna sia a metodi che a campi e campi statici
  • Associato all'istanza della classe che racchiude, quindi per creare un'istanza è necessario innanzitutto un'istanza della classe esterna (notare il nuovo posto della parola chiave):

    Outerclass.InnerClass innerObject = outerObject.new Innerclass();
  • Non è possibile definire alcun membro statico stesso

  • Impossibile avere la dichiarazione di classe o interfaccia

Classe nidificata statica

  • Impossibile accedere ai metodi o ai campi dell'istanza di classe esterna

  • Non associato a nessuna istanza della classe che racchiude Quindi per istanziarlo:

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

Somiglianze

  • Entrambe le classi interne possono accedere anche a campi privati ​​e metodi di classe esterna
  • Anche la classe esterna ha accesso a campi privati ​​e metodi di classi interne
  • Entrambe le classi possono avere modificatore di accesso privato, protetto o pubblico

Perché usare le classi nidificate?

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

  • È un modo per raggruppare logicamente le classi che vengono utilizzate solo in una posizione: se una classe è utile solo per un'altra classe, è logico incorporarla in quella classe e tenere insieme le due cose. La nidificazione di tali "classi di supporto" rende il loro pacchetto più snello.

  • Aumenta l'incapsulamento: considera due classi di livello superiore, 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, B stessa può essere nascosta dal mondo esterno.

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


26

Penso che la convenzione generalmente seguita sia questa:

  • la classe statica all'interno di una classe di livello superiore è una classe nidificata
  • una classe non statica all'interno di una classe di livello superiore è una classe interna , che ha inoltre altre due forme:
    • classe locale - classi denominate dichiarate all'interno di un blocco come un metodo o un corpo del costruttore
    • classe anonima - classi senza nome le cui istanze sono create in espressioni e dichiarazioni

Tuttavia, alcuni altri punti da ricordare sono:

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

  • Le classi interne hanno accesso alle variabili di istanza dell'istanza che racchiude la classe [parent] esterna. Tuttavia, non tutte le classi interne hanno istanze racchiuse, ad esempio le classi interne in contesti statici, come una classe anonima utilizzata in un blocco di inizializzatore statico, no.

  • La classe anonima per impostazione predefinita estende la classe genitore o implementa l'interfaccia genitore e non vi è alcuna clausola ulteriore per estendere qualsiasi altra classe o implementare altre interfacce. Così,

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

Sento che la domanda più grande che rimane aperta quale usare e quando? Bene, dipende principalmente dallo scenario con cui hai a che fare, ma leggere la risposta data da @jrudolph può aiutarti a prendere qualche decisione.


15

Classe nidificata: classe all'interno della classe

tipi:

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

Differenza:

Classe nidificata non statica [Classe interna]

Nella classe nidificata non statica esiste un oggetto della classe interna all'interno dell'oggetto della classe esterna. In modo che quel membro di dati della classe esterna sia accessibile alla classe interna. Quindi per creare un oggetto di classe interna dobbiamo prima creare un oggetto di classe esterna.

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

Classe nidificata statica

Nella classe nidificata statica, l'oggetto della classe interna non ha bisogno dell'oggetto della classe esterna, poiché la parola "statico" indica che non è necessario creare l'oggetto.

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

13

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

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

Le classi nidificate statiche non sono accoppiate con l'oggetto esterno, sono più veloci e non occupano memoria heap / stack, perché non è necessario creare un'istanza di tale classe. Pertanto, la regola empirica è provare a definire la classe nidificata statica, con l'ambito il più limitato possibile (privato> = classe> = protetta> = pubblica), quindi convertirla in classe interna (rimuovendo l'identificatore "statico") e allentare l'ambito, se è davvero necessario.


2
La prima frase non è corretta Non esiste una cosa come " l' istanza della classe interna", e istanze di essa possono essere create in qualsiasi momento dopo che la classe esterna è stata istanziata. La seconda frase non segue dalla prima frase.
Marchese di Lorne,

11

Esiste una sottigliezza sull'uso delle classi statiche nidificate che potrebbe essere utile 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 non viene invocato il costruttore della classe, o almeno fino a quando non viene fatto riferimento per la prima volta agli attributi, 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 "nidificato" e "innerItem" sono entrambi dichiarati "finali statici". l'impostazione di nested.innerItem non ha luogo fino a quando la classe non viene istanziata (o almeno fino a quando non viene fatto riferimento all'elemento statico nidificato per la prima volta), come puoi vedere tu stesso commentando e commentando le righe a cui faccio riferimento, sopra. Lo stesso non vale per 'outerItem'.

Almeno questo è quello che vedo in Java 6.0.


10

I termini sono usati in modo intercambiabile. Se si vuole essere davvero pedanti su di esso, allora si potrebbe definire la "classe annidata" per fare riferimento a una classe interna statica, uno che non ha alcun esempio di cinta. Nel codice, potresti avere qualcosa del genere:

public class Outer {
    public class Inner {}

    public static class Nested {}
}

Tuttavia, questa non è una definizione ampiamente accettata.


2
"statico interno" è una contraddizione in termini.
Marchese di Lorne,

5
Non è una convenzione che definisce la classe interna come una classe nidificata non statica, ma la JLS. docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.1.3
Lew Bloch,

1
E i termini non sono "usati in modo intercambiabile".
Marchese di Lorne,

perché statico nell'esempio sopra che dà errore in ide
DeV

10

Nel caso della creazione dell'istanza, l'istanza della classe interna non statica viene creata con il riferimento all'oggetto della classe esterna in cui è definita. Ciò significa che ha un'istanza inclusiva. Ma l'istanza della classe interna statica viene creata con il riferimento della classe esterna, non con il riferimento all'oggetto della classe esterna. Ciò significa che non ha inclusione inclusiva.

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

1
"statico interno" è una contraddizione in termini. Una classe nidificata è statica o interna.
Marchese di Lorne,

9

Non penso che ci sia molto da aggiungere qui, la maggior parte delle risposte spiega perfettamente le differenze tra classe nidificata statica e classi interne. Tuttavia, considerare il seguente problema quando si utilizzano classi nidificate vs classi interne. Come menzionato in un paio di risposte, le classi interne non possono essere istanziate senza e istanza della loro classe che racchiude, il che significa che tengono un puntatore all'istanza della loro classe che racchiude che può portare a overflow di memoria o stack overflow a causa del fatto che il GC non sarà in grado di eseguire la garbage collection delle classi che la racchiudono anche se non vengono più utilizzate. Per chiarire questo, controlla il codice seguente:

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 pubblicherà " Sono distrutto! ", Ma mantenendo questo commento non lo farà.
Il motivo è che l'istanza interna bianca fa ancora riferimento a GC non può raccoglierla e poiché fa riferimento (ha un puntatore a) all'istanza esterna non viene raccolta. Avere abbastanza oggetti di questo tipo nel progetto e esaurire la memoria.
Rispetto alle classi interne statiche che non contengono un punto all'istanza della classe interna perché non è correlata all'istanza ma alla classe. Il programma sopra può stampare " Sono distrutto! " Se si rende la classe Inner statica e istanziata conOuter.Inner i = new Outer.Inner();




8

Ummm ... una classe interna È una classe nidificata ... intendi classe anonima e classe interna?

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

public class A {
    public class B {
    }
}

Considerando che una classe anonima è un'estensione di una classe definita in modo anonimo, quindi non viene definita alcuna classe "effettiva, come in:

public class A {
}

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

Ulteriore modifica:

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

Esiste una sottile differenza tra classe nidificata statica e non statica ... in sostanza le classi interne non statiche hanno accesso implicito ai campi di istanza e ai metodi della classe che lo racchiude (quindi non possono essere costruite 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.


3
Secondo la documentazione Java, esiste una differenza tra una classe interna e una classe nidificata statica - le classi nidificate statiche non hanno riferimenti alla loro classe che la racchiude e sono utilizzate principalmente a fini organizzativi. Dovresti vedere la risposta di Jegschemesch per una descrizione più approfondita.
mipadi,

1
Penso che la differenza semantica sia principalmente storica. Quando ho scritto un compilatore C # -> Java 1.1, il riferimento al linguaggio Java era molto esplicito: la classe nidificata è statica, la classe interna non lo è (e quindi ha questo $ 0). Ad ogni modo è confuso e sono contento che non sia più un problema.
Tomer Gabel,

2
Il JLS definisce la "classe interna" in docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.1.3 ed è per questo che è impossibile avere un "interno" non statico classe "in Java. "Nidificato" NON è "solo un altro termine per indicare la stessa cosa", e NON È VERO che "una classe interna è una classe definita all'interno di una classe (statica o no)". Queste sono informazioni errate.
Lew Bloch,

6

Targeting per studente, che è alle prime armi in Java e / o classi nidificate

Le classi nidificate possono essere:
1. Classi nidificate statiche.
2. Classi nidificate non statiche. (noto anche come classi interne ) => Ricorda questo


1.
Esempio di classi interne :

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


Le classi interne sono sottoinsiemi di classi nidificate:

  • la classe interna è un tipo specifico di classe nidificata
  • le classi interne sono sottoinsiemi di classi nidificate
  • Puoi dire che anche una classe interna è una classe nidificata, ma NON puoi dire che una classe nidificata sia anche una classe interna .

Specialità di classe interna:

  • l'istanza di una classe interna ha accesso a tutti i membri della classe esterna, anche a quelli 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 chiusa

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: istanza di una classe nidificata statica da una classe che la racchiude

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à di lezioni statiche:

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

Conclusione:
domanda: qual è la differenza principale tra una classe interna e una classe annidata statica in Java?
Risposta: basta esaminare le specifiche di ciascuna classe sopra menzionata.



6

La classe interna e la classe statica nidificata in Java sono entrambe classi dichiarate all'interno di un'altra classe, nota come classe di livello superiore in Java. Nella terminologia Java, se si dichiara una classe nidificata statica, verrà chiamata classe statica nidificata in Java mentre la classe nidificata non statica viene semplicemente denominata Classe interna.

Che cos'è la classe interna in Java?

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

1) Classe interna locale - è dichiarata all'interno di un blocco o metodo di codice.
2) Classe interna anonima - è una classe che non ha un nome a cui fare riferimento e inizializzata nello stesso posto in cui viene creata.
3) Classe interna membro: viene 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 nidificata è un'altra classe dichiarata all'interno di una classe come membro e resa statica. La classe statica nidificata viene inoltre dichiarata come membro della 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 chiusa della classe esterna. Inoltre non è necessaria alcuna istanza della classe esterna per creare un'istanza della classe statica nidificata in Java .

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

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


2
"La classe nidificata statica non può accedere a un membro o metodo di dati non statici (istanza)." è errato e causa confusione . Hanno assolutamente accesso alle informazioni dell'istanza privata, a condizione che creino un'istanza per accedere a tali informazioni. Non hanno un'istanza chiusa come fanno le classi interne, ma hanno accesso ai membri privati ​​dell'istanza della loro classe chiusa.
TJ Crowder,

5

Penso che la gente qui dovrebbe notare che Poster: Classe Nest statica è solo la prima classe interna. Per 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, riassumendo, la classe statica non dipende dalla classe che contiene. Quindi, non possono andare in classe normale. (perché la classe normale necessita di un'istanza).


2
Questa è tutta una sciocchezza. Tutto ciò mostra che una classe interna non può contenere una classe statica. La parte su "non dipende da quale classe contiene" non ha senso, come la frase seguente.
Marchese di Lorne,

5

Quando dichiariamo una classe membro statica all'interno di una classe, è nota come classe nidificata di livello superiore 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, questa è nota come classe interna. La classe interna può essere dimostrata come di seguito:

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

"Quando dichiariamo una classe membro statica all'interno di una classe, è nota come classe nidificata di livello superiore" Non ha senso. "Una classe di livello superiore è una classe che non è una classe nidificata." Non esiste una "classe nidificata di livello superiore".
Radiodef,

3

Di seguito è riportato un esempio di static nested classe 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

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

Diamo un'occhiata ai due seguenti esempi.

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

Per BankAccount utilizziamo una classe nidificata statica, principalmente perché

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

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

  3. BankAccount.Builder è associato solo a BankAccount. Nessun'altra classe è correlata 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 è la definizione di un gestore eventi. https://docs.oracle.com/javase/tutorial/uiswing/events/generalrules.html

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

  1. MyAdapter di classe interna deve accedere al membro di classe esterno.

  2. Nell'esempio, MyAdapter è associato solo a MyClass. Nessun'altra classe è correlata a MyAdapter. quindi è meglio organizzarli insieme senza usare una convenzione dei 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
        }
    }
}

2

Un diagramma

inserisci qui la descrizione dell'immagine

La differenza principale tra static nestede le non-static nestedclassi è che static nested non ha accesso ai membri di classe esterni non statici


0

Prima di tutto non esiste una classe del genere chiamata classe statica. L'uso del modificatore statico con la classe interna (chiamata come classe nidificata) afferma che è un membro statico della classe esterna, il che significa che possiamo accedervi come con altri membri statici e senza avere alcun istanza della classe esterna. (Che è il vantaggio di statico in origine.)

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

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

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

Ma se Class è nidificata, la sintassi è:

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

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


1
"... dice che è un membro statico di Outer Class che significa ....": Non è errato pensare a una classe annidata statica come a "una classe membro" di Outer Class, ma le somiglianze con i campi statici e i metodi finiscono qui. Una classe nidificata statica non "appartiene" alla classe esterna. In quasi tutti i modi che contano, una classe nidificata statica è una classe di livello superiore indipendente la cui definizione di classe è stata nidificata all'interno di quella della classe esterna per comodità di imballaggio (e, si spera, perché esiste un'associazione logica tra la classe nidificata e la classe esterna ... anche se non ce n'è bisogno).
Scott

1
"statico interno" è una contraddizione in termini. Le classi statiche esistono, al primo livello di nidificazione, e non sono classi interne, per definizione. Molto confuso.
Marchese di Lorne,

0

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

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

Le classi nidificate 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 da tenere a mente è che le classi nidificate non statiche (classi interne) hanno accesso ad altri membri della classe che la racchiude, anche se sono dichiarate private. Le classi nidificate statiche hanno accesso ad altri membri della classe che la racchiude solo se sono statiche. Non può accedere a membri non statici della classe esterna. Come per 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 interna, è innanzitutto necessario creare un'istanza della 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 nidificate

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

Fonte: Tutorial Java ™ - Classi nidificate


-1

La differenza è che una dichiarazione di classe nidificata che è anche statica può essere istanziata al di fuori della classe che la racchiude.

Quando si dispone di una dichiarazione di classe nidificata non statica, nota anche come classe interna , Java non consente di creare un'istanza se non tramite la classe che la racchiude. L'oggetto creato dalla classe interna è collegato all'oggetto creato dalla classe esterna, quindi la classe interna può fare riferimento ai campi dell'esterno.

Ma se è statico, allora il collegamento non esiste, non è possibile accedere ai campi esterni (tranne tramite un riferimento ordinario come qualsiasi altro oggetto) e quindi è possibile creare un'istanza della classe nidificata da sola.


1
Questo non è vero. Esiste una sintassi speciale per la creazione di una classe interna al di fuori dell'ambito della classe che la racchiude.
Marchese di Lorne,

-1

È piuttosto semplice, confrontando le classi locali statiche e le classi interne non statiche
Differenze:
Classe locale statica:
può accedere solo ai membri statici della classe esterna.
Impossibile avere inizializzatori statici
Non è possibile accedere direttamente dall'esterno della funzione in cui è dichiarata


-2

Ho illustrato vari possibili scenari corretti ed errori che possono verificarsi nel codice 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);
                        }*/
                    //}
                }
    }

1
Ovviamente la parte di codice. E nel caso non l'avessi notato: il tuo esempio di codice è super difficile da leggere. Anche sul mio enorme monitor desktop ho una barra di scorrimento orizzontale. Prendi in considerazione l'idea di inserire i tuoi commenti sopra o sotto quello che stanno commentando, anziché dietro .
GhostCat,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.