it-swarm-eu.dev

Java vnitřní třída a statická vnořená třída

Jaký je hlavní rozdíl mezi vnitřní třídou a statickou vnořenou třídou v jazyce Java? Zahrnuje design/implementace roli při výběru jednoho z nich?

1585
Omnipotent

Z Java Tutorial :

Vnořené třídy jsou rozděleny do dvou kategorií: statické a statické. Vnořené třídy, které jsou deklarovány staticky, se jednoduše nazývají statické vnořené třídy. Nestatické vnořené třídy se nazývají vnitřní třídy. 

Ke statickým vnořeným třídám se přistupuje pomocí názvu přiložené třídy:

OuterClass.StaticNestedClass

Chcete-li například vytvořit objekt pro statickou vnořenou třídu, použijte tuto syntaxi:

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

Objekty, které jsou instancemi vnitřní třídy, existují v rámci instance vnější třídy. Zvažte následující třídy:

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

Instance InnerClass může existovat pouze v instanci OuterClass a má přímý přístup k metodám a polím její instance instance.

Chcete-li vytvořit instanci vnitřní třídy, musíte nejprve vytvořit instanci vnější třídy. Potom vytvořte vnitřní objekt uvnitř vnějšího objektu s touto syntaxí:

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

viz: Java Tutorial - Nested Classes

Pro úplnost si všimněte, že existuje i taková věc jako vnitřní třída bez uzavřené instance :

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

new A() { ... } je zde třída inner definovaná ve statickém kontextu a nemá uzavřenou instanci.

1564
Martin

Nemyslím si, že skutečný rozdíl ve výše uvedených odpovědích byl jasný. 

Nejprve získáte právo na podmínky: 

  • Vnořená třída je třída, která je obsažena v jiné třídě na úrovni zdrojového kódu.
  • Je statický, pokud jej deklarujete pomocí static modifikátoru.
  • Nestatická vnořená třída se nazývá vnitřní třída. (Zůstanu s nestatickou vnořenou třídou.)

Martinova odpověď je zatím správná. Skutečná otázka však zní: Jaký je účel deklarování vnořené třídy statické nebo ne?

Používáte statické vnořené třídy pokud chcete udržet své třídy dohromady, pokud patří lokálně dohromady nebo pokud je vnořená třída používána výhradně v uzavřené třídě. Neexistuje žádný sémantický rozdíl mezi statickou vnořenou třídou a každou jinou třídou.

Nestatické vnořené třídy jsou jiné zvíře. Podobně jako u anonymních vnitřních tříd jsou tyto vnořené třídy vlastně uzávěry. To znamená, že zachytí jejich okolí a jejich uzavírající instanci a zpřístupní je. Možná to to objasní. Zobrazit tento pahýl kontejneru:

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

V tomto případě chcete mít odkaz z podřízené položky na nadřazený kontejner. Použití nestatické vnořené třídy, to funguje bez nějaké práce. Můžete přistupovat k uzavírací instanci kontejneru se syntaxí Container.this.

Další hardcore vysvětlení:

Pokud se podíváte na bajtové kódy jazyka Java, kompilátor vygeneruje pro (nestatickou) vnořenou třídu, která by mohla být ještě jasnější:

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

Jak vidíte, kompilátor vytvoří skryté pole Container this$0. Toto je nastaveno v konstruktoru, který má další parametr typu Container, který specifikuje instanci pro uzavření. Tento parametr nelze zobrazit ve zdroji, ale kompilátor implicitně vygeneruje pro vnořenou třídu. 

Martinův příklad

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

by se tak zkompiloval na volání něco podobného (v bytecodes)

new InnerClass(outerObject)

Pro úplnost:

Anonymní třída je je dokonalým příkladem nestatické vnořené třídy, která s ní nemá žádné jméno a nemůže být na ni odkazována později.

131
jrudolph

Myslím si, že žádná z výše uvedených odpovědí vám nevysvětluje skutečný rozdíl mezi vnořenou třídou a statickou vnořenou třídou z hlediska návrhu aplikace: 

OverView

Vnořená třída může být statická nebo statická a v každém případě je třída definovaná v rámci jiné třídy . Vnořená třída by měla existovat pouze k tomu, aby sloužila, je uzavírající třída , pokud je vnořená třída užitečná jinými třídami (nejen uzavřením), měla by být deklarována jako třída nejvyšší úrovně.

Rozdíl

Nonstatic Nested class : je implicitně asociován s uzavírací instancí třídy obsahující, což znamená, že je možné vyvolat metody a přístupové proměnné v uzavřené instanci. Jedním z běžných použití nestatické vnořené třídy je definovat třídu adaptéru.

Statická vnořená třída : nemůže přistupovat k instanci uzavírající třídy a vyvolávat metody na ní, takže by měla být použita, pokud vnořená třída nevyžaduje přístup k instanci uzavřené třídy. Běžným použitím statické vnořené třídy je implementace komponent vnějšího objektu.

Závěr

Takže hlavní rozdíl mezi těmito dvěma z hlediska návrhu je: nestatická vnořená třída může přistupovat k instanci třídy kontejneru, zatímco statický nemůže.

88
aleroot

V jednoduchých termínech potřebujeme vnořené třídy především proto, že Java neposkytuje uzávěry.

Vnořené třídy jsou třídy definované uvnitř těla jiné uzavřené třídy. Jedná se o dva typy - statické a nestatické.

Jsou považovány za členy uzavřené třídy, a proto můžete zadat libovolný ze čtyř specifikátorů přístupu - private, package, protected, public. Tento luxus nemáme s prvotřídními třídami, které lze deklarovat pouze public nebo package-private.

Vnitřní třídy aka Non-stack třídy mají přístup k ostatním členům nejvyšší třídy, i když jsou deklarovány jako soukromé, zatímco statické vnořené třídy nemají přístup k ostatním členům nejvyšší třídy.

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

Inner1 je naše statická vnitřní třída a Inner2 je naše vnitřní třída, která není statická. Klíčový rozdíl mezi nimi nelze vytvořit instanci Inner2 bez Outeru, kde můžete objekt Inner1 vytvořit nezávisle.

Kdy byste použili třídu Inner?

Přemýšlejte o situaci, kdy jsou Class A a Class B příbuzné, Class B potřebuje přístup k Class A členům a Class B se vztahuje pouze k Class A. Vnitřní třídy přicházejí do obrazu.

Pro vytvoření instance vnitřní třídy je třeba vytvořit instanci své vnější třídy.

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

nebo

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

Kdy byste použili statickou vnitřní třídu?

Definujete statickou vnitřní třídu, když víte, že nemá žádný vztah s instancí uzavírací třídy/nejvyšší třídy. Pokud vaše vnitřní třída nepoužívá metody nebo pole vnější třídy, je to jen ztráta místa, takže je statická.

Chcete-li například vytvořit objekt pro statickou vnořenou třídu, použijte tuto syntaxi:

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

Výhodou statické vnořené třídy je to, že nepotřebuje objekt obsahující třídu/top class k práci. To vám může pomoci snížit počet objektů, které aplikace vytvoří za běhu.

31
Thalaivar

Myslím si, že konvencí, která je obecně dodržována, je toto:

  • statická třída uvnitř třídy nejvyšší úrovně je vnořená třída
  • nestatická třída ve třídě nejvyšší úrovně je vnitřní třída , která dále má dva další formy:
    • místní třídy - pojmenované třídy deklarované uvnitř bloku jako metoda nebo tělo konstruktoru
    • anonymní třída - nejmenované třídy, jejichž instance jsou vytvořeny ve výrazech a příkazech

Nicméně jen málo dalších bodů na vzpomínky jsou:

  • Třídy nejvyšší úrovně a statická vnořená třída jsou sémanticky stejné s tím rozdílem, že v případě statické vnořené třídy může vytvořit statický odkaz na soukromá statická pole/metody třídy Outer [parent] a naopak.

  • Vnitřní třídy mají přístup k proměnným instance uzavřené instance třídy Outer [parent]. Ne všechny vnitřní třídy však mají uzavřené instance, například vnitřní třídy ve statických kontextech, jako anonymní třída použitá ve statickém bloku inicializátoru, ne.

  • Anonymní třída standardně rozšiřuje nadřazenou třídu nebo implementuje nadřazené rozhraní a neexistuje žádná další klauzule pro rozšíření jakékoli jiné třídy nebo implementace dalších rozhraní. Tak,

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

Cítím, že větší otázka, která zůstane otevřená a která se použije a kdy? No, že většinou záleží na tom, co scénář máte co do činění, ale čtení odpovědi od @ jrudolph vám může pomoci udělat nějaké rozhodnutí.

26
sactiw

Zde jsou klíčové rozdíly a podobnosti mezi vnitřní třídou Java a statickou vnořenou třídou.

Doufám, že to pomůže!

Vnitřní třída

  • Může přistupovat k metodám a polím třídy jak instance, tak statickým
  • Přidruženo k instanci uzavřené třídy tak, aby se vytvořila instanci, nejprve potřebuje instanci vnější třídy (poznámka nové klíčové slovo klíčového slova):

    Outerclass.InnerClass innerObject = outerObject.new Innerclass();
    
  • Nelze definovat žádné statické členy samotné

  • Nelze mít deklaraci Třída nebo Rozhraní

Statická vnořená třída

  • Nelze získat přístup k metodám nebo polím vnější třídy instance

  • Nejsou spojeny s žádnou instancí uzavírací třídy

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

Podobnosti

  • Obě Vnitřní třídy mohou přistupovat i do soukromých polí a metod z vnější třídy
  • Také Outer class má přístup k soukromým polím a metodám of inner classes
  • Obě třídy mohou mít soukromý, chráněný nebo veřejný přístupový modifikátor

Proč používat vnořené třídy?

Podle dokumentace společnosti Oracle existuje několik důvodů ( plná dokumentace ):

  • Je to způsob logického seskupování tříd, které se používají pouze na jednom místě: Pokud je třída užitečná pouze pro jednu jinou třídu, je logické vložit ji do této třídy a udržet tyto dva dohromady. Vnoření takových „pomocných tříd“ činí jejich balíček efektivnějším.

  • Zvyšuje zapouzdření: Uvažujme o dvou špičkových třídách, A a B, kde B potřebuje přístup k členům A, kteří by jinak byli prohlášeni za soukromí. Skrytím třídy B do třídy A mohou být členové A deklarováni jako soukromí a B k nim může přistupovat. Navíc, B sám může být skryt od vnějšího světa.

  • To může vést k čitelnějšímu a udržovatelnějšímu kódu: Vnoření malých tříd do tříd nejvyšší úrovně umístí kód blíže k místu, kde se používá.

26
Behzad Bahmanyar

Vnořená třída: třída uvnitř třídy

Typy:

  1. Statická vnořená třída
  2. Nestatická vnořená třída [Inner class]

Rozdíl:

Nestatická vnořená třída [Vnitřní třída]

V nestatické vnořené třídě existuje objekt vnitřní třídy uvnitř objektu vnější třídy. Takže datový člen vnější třídy je přístupný vnitřní třídě. Abychom vytvořili objekt vnitřní třídy, musíme nejprve vytvořit objekt vnější třídy.

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

Statická vnořená třída

Ve statické vnořené třídě objekt vnitřní třídy nepotřebuje objekt vnější třídy, protože slovo "statický" neindikuje potřebu vytvářet objekt.

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

Pokud chcete přistupovat k systému x, zadejte následující vnitřní metodu

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

Tam je jemnost o použití vnořených statických tříd, které by mohly být užitečné v určitých situacích.

Zatímco statické atributy se dostanou do instancí před tím, než se třída vytvoří pomocí konstruktoru, Statické atributy uvnitř vnořených statických tříd se nezdají být instancovány až po vyvolání konstruktoru třídy Nebo alespoň ne. až poté, co jsou atributy poprvé odkazovány, , i když jsou označeny jako „konečné“.

Zvažte tento příklad:

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

I když jsou 'vnořené' a 'innerItem' prohlášeny za statické. nastavení nested.innerItem se neuskuteční až do okamžiku, kdy je třída vytvořena instancí (nebo alespoň ne až po prvním odkazování na vnořenou statickou položku), jak vidíte sami [ komentováním a oddělováním řádků, na které odkazuji výše. Totéž neplatí Pro 'externalItem'.

Alespoň to je to, co vidím v jazyce Java 6.0.

11
HippoMan

Instance vnitřní třídy je vytvořena, když je vytvořena instance vnější třídy. Proto členové a metody vnitřní třídy mají přístup k členům a metodám instance (objektu) vnější třídy. Když instance vnější třídy vyjde mimo rozsah, přestanou existovat i instance vnitřní třídy.

Statická vnořená třída nemá konkrétní instanci. Je to právě načten, když je používán poprvé (stejně jako statické metody). Je to zcela nezávislá entita, jejíž metody a proměnné nemají přístup k instancím vnější třídy.

Statické vnořené třídy nejsou propojeny s vnějším objektem, jsou rychlejší a nevyužívají paměť haldy/zásobníku, protože není nutné vytvořit instanci takové třídy. Proto je pravidlem pokusit se definovat statickou vnořenou třídu s co nejmenším omezeným rozsahem (private> = class> = protected> = public) a poté ji převést na vnitřní třídu (odstraněním "statického" identifikátoru) a uvolněním pokud je to opravdu nutné.

11
rmaruszewski

Nemyslím si, že by zde bylo co dodat, většina odpovědí dokonale vysvětluje rozdíly mezi statickou vnořenou třídou a vnitřními třídami. Při použití vnořených tříd vs vnitřní třídy však zvažte následující problém. Jak je zmíněno v několika odpovědích, vnitřní třídy nemohou být instancovány bez a instancí jejich uzavřené třídy, což znamená, žeHOLDa ukazatel k instanci jejich uzavřené třídy, která může vést k přetečení paměti nebo výjimce přetečení zásobníku kvůli skutečnosti, že GC nebude schopna sbírat uzavřené třídy, i když se již nepoužívají. Chcete-li toto jasné, zkontrolujte následující kód: 

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

}

Pokud odstraníte komentář k // inner = null; Program bude vyřazen " Jsem zničen! ", ale ponechání tohoto komentáře nebude.
Důvodem je to, že bílá vnitřní instance je stále odkazována GC nemůže sbírat a protože odkazuje (má ukazatel na) vnější instanci, není také shromažďována. Mít dostatek těchto objektů ve vašem projektu a může spustit nedostatek paměti.
Ve srovnání se statickými vnitřními třídami, které nedrží bod k instanci vnitřní třídy, protože se nejedná o instanci, ale o třídu. Výše ​​uvedený program může tisknout " Jsem zničený! ", pokud uděláte vnitřní třídu statickou a instancí pomocí Outer.Inner i = new Outer.Inner(); 

10
Adelin

V případě vytváření instance je instalována instance statické vnitřní třídy S odkazem na objekt Vnější třídy, ve které je definována. Znamená to, že má instanci instanci. Ale instance statické vnitřní třídy Je vytvořena s odkazem na vnější třídu, nikoliv s Odkazem objektu vnější třídy. To znamená, že Nemají instanci instanci.

Například:

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

Termíny jsou používány zaměnitelně. Pokud chcete být opravdu pedantní o tom, pak mohl definovat "vnořenou třídu" odkazovat na statickou vnitřní třídu, která nemá žádnou uzavírací instanci. V kódu můžete mít něco takového:

public class Outer {
    public class Inner {}

    public static class Nested {}
}

To však není široce přijímaná definice.

8
Daniel Spiewak

Vnořená třída je velmi obecný pojem: každá třída, která není nejvyšší úrovní, je vnořená třída. Vnitřní třída je nestatická vnořená třída. Joseph Darcy napsal velmi pěkné vysvětlení o Vnořené, Vnitřní, Členové a Třídy nejvyšší úrovně .

8
Wouter Coekaerts

Cílení na žáka, který je nováčkem jazyka Java a/nebo vnořených tříd 

Vnořené třídy mohou být:
1. Statické vnořené třídy.
2. Nestatické vnořené třídy. (také známý jako Vnitřní třídy ) => Zapamatujte si to


1.Vnitřní třídy
Příklad:

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


Vnitřní třídy jsou podmnožiny vnořených tříd:

  • vnitřní třída je specifický typ vnořené třídy
  • vnitřní třídy jsou podmnožiny vnořených tříd
  • Můžete říci, že třída inner je také vnořená třída, ale můžeteNEříci, že vnořená třída je také vnitřní třída

Specialita vnitřní třídy:

  • instanci vnitřní třídy má přístup ke všem členům vnější třídy, dokonce i těm, které jsou označeny jako „soukromé“


2.Statické vnořené třídy:
Příklad:

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

Případ 1: Instantování statické vnořené třídy z neuzavřené třídy

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

Případ 2: Instantování statické vnořené třídy z uzavřené třídy

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

}

Speciální statické třídy:

  • Statická vnitřní třída by měla přístup pouze ke statickým členům vnější třídy a nemá přístup k nestatickým členům.

Závěr:
Question: Jaký je hlavní rozdíl mezi vnitřní třídou a statickou vnořenou třídou v jazyce Java?
Odpověď: Jen projít specifika každé třídy uvedené výše.

7
VdeX

Ummm ... vnitřní třída IS vnořená třída ... máte na mysli anonymní třídu a vnitřní třídu?

Edit: Pokud jste vlastně znamenali vnitřní vs anonymní ... vnitřní třída je jen třída definovaná v rámci třídy, jako například:

public class A {
    public class B {
    }
}

Zatímco anonymní třída je rozšířením třídy definované anonymně, tak není definována žádná skutečná třída, jako v:

public class A {
}

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

Další úprava:

Wikipedia tvrdí, že je rozdíl v Javě, ale s Jávou jsem pracoval 8 let a je to první, co jsem slyšel takový rozdíl ... nemluvě o tom, že tam nejsou žádné odkazy na zálohování nároku ... spodní řádek, vnitřní třída je třída definovaná uvnitř třídy (statická nebo ne) a vnořená je jen další termín, který znamená stejnou věc.

Existuje statický rozdíl mezi statickou a nestatickou vnořenou třídou ... v podstatě nestatické vnitřní třídy mají implicitní přístup k instancím a metodám instance uzavřené třídy (tedy nemohou být konstruovány ve statickém kontextu, bude to kompilátor) chyba). Na druhé straně statické vnořené třídy nemají implicitní přístup k instancím a metodám instance a mohou být konstruovány ve statickém kontextu.

7
Mike Stone

Vnitřní třída a vnořená statická třída v Javě jsou obě třídy deklarovány uvnitř jiné třídy, známé jako třída nejvyšší úrovně v jazyce Java. V terminologii Java Pokud deklarujete statickou statickou vnořenou třídu, bude v jazyce Java nazýváno vnořenou statickou třídou, zatímco nestatická vnořená třída bude jednoduše označována jako vnitřní třída. 

Co je to vnitřní třída v jazyce Java?

Jakákoliv třída, která není nejvyšší úrovní nebo je deklarována v jiné třídě, je známa jako vnořená třída az těchto vnořených tříd se třída, která je deklarována jako statická, označuje jako třída Inner v jazyce Java. existují tři druhy třídy Inner v Javě:

1) Lokální vnitřní třída - je deklarována uvnitř kódového bloku nebo metody.
2) Anonymní vnitřní třída - je třída, která nemá jméno k odkazu a je inicializována na stejném místě, kde je vytvořena.
3) Vnitřní třída členu - je deklarována jako statická součást vnější třídy.

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

Co je vnořená statická třída v jazyce Java?

Vnořená statická třída je jiná třída, která je deklarována uvnitř třídy jako člen a je statická. Vnořená statická třída je také deklarována jako člen vnější třídy a může být soukromá, veřejná nebo chráněná jako každý jiný člen. Jednou z hlavních výhod vnořené statické třídy nad vnitřní třídou je to, že instance vnořené statické třídy není připojena k žádné uzavírací instanci třídy Outer. Rovněž nepotřebujete žádnou instanci třídy Outer k vytvoření instance vnořené statické třídy v jazyce Java.

1) Může přistupovat k statickým datovým členům vnější třídy včetně soukromých.
2) Statická vnořená třída nemůže přistupovat k nestatickým (instančním) členům dat nebo metodě.

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

Ref: Vnitřní třída a vnořená statická třída v jazyce Java s příkladem

6
roottraveller

Když deklarujeme statickou třídu členů uvnitř třídy, je označována jako vnořená třída nejvyšší úrovně nebo statická vnořená třída. Lze to prokázat takto: 

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

Když deklarujeme nestatickou třídu členů uvnitř třídy, je označována jako vnitřní třída. Vnitřní třída může být demonstrována níže: 

    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

Myslím, že lidé by si měli povšimnout, že plakát, který: Static Nest Class je jen první vnitřní třídou. Například:

 public static class A {} //ERROR

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

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

 }

Souhrnná statická třída tedy nezávisí na tom, která třída obsahuje. Takže nemohou v normální třídě. (protože normální třída potřebuje instanci).

5
hqt

Následuje příklad static nested class a 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

Myslím, že žádná z výše uvedených odpovědí vám neposkytuje skutečný příklad rozdílu mezi vnořenou třídou a statickou vnořenou třídou z hlediska návrhu aplikace. Hlavním rozdílem mezi statickou vnořenou třídou a vnitřní třídou je možnost přístupu k poli instance vnější třídy.

Podívejme se na dva následující příklady.

Static nest nestate: Statické vnořené třídy jsou dobrým příkladem použití modelu builderu ( https://dzone.com/articles/design-patterns-the-builder-pattern ).

Pro BankAccount používáme statickou vnořenou třídu, hlavně proto, že

  1. Třída instancí statického hnízda by mohla být vytvořena před vnější třídou.

  2. Tvůrce je ve vzorci tvůrce pomocnou třídou, která se používá k vytvoření účtu BankAccount.

  3. BankAccount.Builder je spojen pouze s účtem BankAccount. Žádné další třídy se nevztahují k BankAccount.Builder. tak je lepší je organizovat společně bez použití konvence.
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;
        }
    }
}

Vnitřní třída: Běžným použitím vnitřních tříd je definovat obslužný program události. https://docs.Oracle.com/javase/tutorial/uiswing/events/generalrules.html

Pro MyClass používáme vnitřní třídu, hlavně proto, že:

  1. Vnitřní třída MyAdapter potřebuje přístup k členu vnější třídy.

  2. V příkladu je MyAdapter spojen pouze s MyClass. Žádné další třídy se nevztahují k MyAdapter. tak je lepší je organizovat společně bez použití konvence

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

Programovací jazyk Java umožňuje definovat třídu v rámci jiné třídy. Tato třída se nazývá vnořená třída a je zobrazena zde:

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

Vnořené třídy jsou rozděleny do dvou kategorií: statické a statické. Vnořené třídy, které jsou deklarovány staticky, se nazývají statické vnořené třídy. Nestatické vnořené třídy se nazývají vnitřní třídy. Statické vnořené třídy mají přístup pouze k ostatním členům uzavřené třídy, pokud jsou statické. Nelze získat přístup k statickým členům vnější třídy. Stejně jako u metod třídy a proměnných je i statická vnořená třída přiřazena k její vnější třídě. Chcete-li například vytvořit objekt pro statickou vnořenou třídu, použijte tuto syntaxi:

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

Chcete-li vytvořit instanci vnitřní třídy, musíte nejprve vytvořit instanci vnější třídy. Potom vytvořte vnitřní objekt uvnitř vnějšího objektu s touto syntaxí:

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

Proč používáme vnořené třídy

  1. Je to způsob logického seskupování tříd, které se používají pouze na jednom místě.
  2. Zvyšuje zapouzdření.
  3. To může vést k čitelnějšímu a udržovatelnějšímu kódu.

Zdroj: Návody Java ™ - Vnořené třídy

0
Mithun Debnath

Nejdříve neexistuje taková třída nazvaná Static class. Statické modifikační použití s ​​vnitřní třídou (nazývá se vnořená třída) říká, že se jedná o statický člen vnější třídy, což znamená, že k němu můžeme přistupovat stejně jako u jiných statických členů a bez jakýchkoli instance třídy Outer. (Což je původně statická výhoda.) 

Rozdíl mezi použitím třídy Nested a běžnou třídou Inner je:

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

Nejdříve můžeme vytvořit instanci Outerclass, pak můžeme vstoupit dovnitř.

Pokud je však třída vnořena, pak je syntaxe:

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

Která používá statickou syntaxi jako normální implementaci statického klíčového slova.

0
Sohi