java - 継承 - クラス 内 クラス メリット




Javaの内部クラスと静的なネストされたクラス (16)

Javaにおける静的および非静的ネストされたクラスの違い

1)ネストされた静的クラスは、Outerクラスの参照を必要としないが、静的でないネストされたクラスまたはInnerクラスは、Outerクラス参照を必要とする。Outerクラスのインスタンスを作成せずにInnerクラスのインスタンスを作成することはできません。これは、ネストされたクラスを静的または非静的にする際に考慮すべき最も重要なことです。

2)静的クラスは実際にはクラスの静的メンバーであり、静的コンテキストや静的メソッド、Outerクラスの静的ブロックなどで使用できます。

3)静的ネストされたクラスと非静的なネストされたクラスの別の違いは、ネストされた静的クラスに直接メソッドやフィールドなどの非静的メンバーにアクセスできないことです。もしあなたが "静的ではないメンバーは静的コンテキストでは使用できません"のようなエラーが出ます。Innerクラスは、Outerクラスの静的メンバーと非静的メンバーの両方にアクセスできますが、

public class OuterClass {
    private static String message = "Hello JAVA";

    // How to create instance of static and non static nested class
    public static void main(String... args) {

        // creating instance of nested Static class
        InnerClassStatic printer = new InnerClassStatic();

        //calling non static method of nested static class
        printer.printMessage();

        // creating instance of non static nested class or InnerClass class
        // In order to create instance of InnerClass class you need an OuterClass class instance
        OuterClass outerClass = new OuterClass(); //outerClass class instance for creating non static nested class

        InnerClass innerClass = outerClass.new InnerClass();
        innerClass.display();  //calling non static method of InnerClass class

        // we can also combine above steps in one step to create instance of InnerClass class
        InnerClass nonStaticIner = new OuterClass().new InnerClass();

        nonStaticIner.display(); // similarly you can now call InnerClass class method
    }


    // Static nested class
    private static class InnerClassStatic {
        //Only static member of OuterClass class is directly accessible in nested static class

        public void printMessage() {
            // Compile time error if message field is not static
            System.out.println("Message from nested static class : " + message);
        }
    }

    //non static nested class - also called InnerClass class
    private class InnerClass {

        // Both static and non static member of OuterClass class is accessible in this InnerClass class
        public void display() {
            System.out.println(" Message from non static nested or InnerClass class : " + message);
        }
    }
}

出力:

Message from nested static class : Hello JAVA
Message from non static nested or Inner class : Hello JAVA
Message from non static nested or Inner class : Hello JAVA

これはJavaの静的ネストクラスと非静的ネストクラスの違いです。これまではメンバーInnerクラスに触れていましたが、Innerクラス(LocalクラスやAnonymous Innerクラスなど)では他の2つのタイプについては説明しませんでした。このJavaチュートリアルでは、Javaでネストされた静的クラスとは何か、およびJavaでネストされた静的クラスと非静的クラスの両方のインスタンスを作成する方法を見てきました。

要約すると、Outerクラスのインスタンスを必要としないため、ネストされた静的クラスのインスタンスを簡単に作成できます。非静的なネストされたクラス(たとえば、Innerクラス)は常にOuterクラスインスタンスを必要とし、Outerクラスなしでは存在できません。静的クラスと静的クラスのどちらかを選択する必要がある場合は、それを使用できる場合は静的ネストされたクラスよりも優先します。

Javaの内部クラスと静的入れ子クラスの主な違いは何ですか? 設計/実装はこれらの1つを選択する際に役割を果たしますか?


Javaチュートリアルから:

ネストされたクラスは、静的と非静的の2つのカテゴリに分類されます。 静的と宣言されたネストされたクラスは、単に静的なネストされたクラスと呼ばれます。 静的でないネストされたクラスは、内部クラスと呼ばれます。

静的なネストされたクラスは、囲むクラス名を使用してアクセスされます。

OuterClass.StaticNestedClass

たとえば、静的ネストされたクラスのオブジェクトを作成するには、次の構文を使用します。

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

内部クラスのインスタンスであるオブジェクトは、外部クラスのインスタンス内に存在します。 次のクラスを考えてみましょう:

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

InnerClassのインスタンスは、OuterClassのインスタンス内にのみ存在し、囲むインスタンスのメソッドとフィールドに直接アクセスできます。

内部クラスをインスタンス化するには、まず外部クラスをインスタンス化する必要があります。 次に、次の構文を使用して外側オブジェクト内の内側オブジェクトを作成します。

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

参照: Javaチュートリアル - ネストされたクラス

完全性のために、内包クラスのインスタンスを持たないクラスあります

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

ここで、 new A() { ... }静的コンテキストで定義された内部クラスであり、囲むインスタンスはありません。


Javaやネストされたクラスの初心者である学習者を対象とする

ネストされたクラスは、次のいずれかになります
。1.静的ネストされたクラス。
2.非静的ネストされたクラス。(Innerクラスとも呼ばれます)=>これを覚えておいてください


1.インナークラス
例:

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


内部クラスは、ネストされたクラスのサブセットです。

  • 内部クラスはネストされたクラスの特定の型です
  • 内部クラスはネストされたクラスのサブセットです
  • あなたは、と言うことができるインナークラスは、ネストしたクラスですが、できないで、ネストされたクラスはまた、内部クラスであることを言います

内クラスのスペシャリスト:

  • 内部クラスのインスタンスは、外部クラスのすべてのメンバ、たとえ "プライベート"とマークされたメンバにもアクセスできます


2.静的ネストされたクラス:
例:

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

ケース1:静的なネストされたクラスを、非囲いのクラスからインスタンス化する

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

ケース2:囲むクラスからスタティックなネストされたクラスをインスタンス化する

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

}

静的クラスの専門分野:

  • 静的内部クラスは、外部クラスの静的メンバーにのみアクセスでき、非静的メンバーにはアクセスできません。

結論:
質問: Javaの内部クラスと静的入れ子クラスの主な違いは何ですか?
答え:上記の各クラスの詳細を参照してください。


Javaの内部クラスネストされた静的クラスはどちらも、Javaのトップレベルクラスと呼ばれる別のクラスの内部で宣言されたクラスです。Javaの用語では、ネストされたクラスを静的宣言すると、Javaではネストされた静的クラスと呼ばれ、静的でないネストされたクラスは単にインナークラスと呼ばれます。

Javaの内部クラスとは何ですか?

最上位ではない、または他のクラスの中で宣言されているクラスは、ネストされたクラスとして知られており、それらのネストされたクラスのうち、非静的と宣言されたクラスはJavaのInnerクラスとして知られています。Javaには3種類のInnerクラスがあります。

1)局所的な内部クラス - コードブロックまたはメソッドの中で宣言される。
2)匿名の内部クラス - 参照する名前を持たず、作成される同じ場所で初期化されるクラスです。
3)メンバ内部クラス - 外部クラスの非スタティックメンバとして宣言されます。

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

Javaのネストされた静的クラスとは何ですか?

ネストされた静的クラスは、クラスの内部でメンバーとして宣言され、静的にされた別のクラスです。ネストされた静的クラスも外部クラスのメンバーとして宣言され、他のメンバーと同様にプライベート、パブリック、または保護されます。内部クラスにネストされた静的クラスの主な利点の1つは、ネストされた静的クラスのインスタンスが、Outerクラスの包囲するインスタンスに接続されていないことです。また、Javaでネストされた静的クラスのインスタンスを作成するために、Outerクラスのインスタンスは必要ありません

1)プライベートクラスを含む外部クラスの静的データメンバーにアクセスできます。
2)静的なネストされたクラスは、非静的(インスタンス)データのメンバーまたはメソッドにアクセスできません。

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

リファレンス:Javaの内部クラスとネストされた静的クラス


ここでは、Javaの内部クラスと静的な入れ子のクラスの主な違いと類似点を示します。

それが役に立てば幸い!

インナークラス

  • インスタンスクラスと静的メソッドの両方の外部クラスにアクセスできます。
  • クラスを囲むインスタンスに関連付けられているため、インスタンス化するにはまず外部クラスのインスタンスが必要です( 新しいキーワードの場所を書き留めます)。

    Outerclass.InnerClass innerObject = outerObject.new Innerclass();
    
  • 静的メンバー自体を定義することはできません

  • クラス宣言またはインターフェイス宣言を持つことはできません

静的ネストされたクラス

  • 外部クラスのインスタンスメソッドまたはフィールドにアクセスできません

  • クラスを囲むインスタンスに関連付けられていないので、インスタンス化する:

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

類似点

  • 両方のInnerクラスは、 private クラスの フィールドおよび 外部クラスの メソッドにもアクセスできます
  • また、 Outerクラスは、 プライベートフィールドや 内部クラスの メソッドにアクセスできます
  • どちらのクラスもプライベート、プロテクト、またはパブリックのアクセス修飾子を持つことができます

ネストされたクラスを使用する理由

Oracleのマニュアルにはいくつかの理由があります( 完全なドキュメント )。

  • これは、1つの場所でのみ使用されるクラスを論理的にグループ化する方法です。あるクラスが他の1つのクラスに有益な場合は、そのクラスに埋め込み、2つのクラスを一緒に保つことは論理的です。 このような「ヘルパークラス」のネストは、パッケージをより合理化します。

  • それはカプセル化を増加させます: BがAのメンバーにアクセスする必要がある2つのトップレベルのクラスAとBを考えてみましょう。そうでなければプライベートと宣言されます。 クラスA内のクラスBを隠すことにより、Aのメンバーはプライベートであると宣言され、Bはそれらにアクセスすることができる。 また、B自体を外部から隠すことができます。

  • より読みやすくメンテナンス可能なコードにつなげることができます。トップレベルのクラス内に小さなクラスを入れ子にすると、コードは使用されている場所の近くに配置されます。


ここに追加することはあまりありませんが、答えのほとんどは静的ネストされたクラスとインナークラスの違いを完全に説明しています。 ただし、ネストされたクラスと内部クラスを使用する場合は、次の点を考慮してください。 いくつかの答えで言及しているように、内部クラスは、その囲むクラスなしでインスタンス化することはできません。つまり、GCが原因でメモリオーバーフローまたはスタックオーバーフローの例外につながる、その囲むクラスのインスタンスへのポインタを保持しますそれ以上使用されなくても、囲むクラスをガベージコレクションすることはできません。 これを明確にするには、以下のコードを調べてください:

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

}

// inner = null;コメントを削除すると、 プログラムは「 私は破壊されました! 」と出しますが、これをコメントしておくことはできません。
その理由は、白い内部インスタンスがまだ参照されているため、GCはそれを収集できません。また、外部インスタンスを参照する(ポインタを持つ)ため、収集されません。 プロジェクトにこれらのオブジェクトが十分にあり、メモリが不足する可能性があります。
インスタンスに関連するクラスではないので、内部クラスインスタンスにポイントを保持しない静的内部クラスと比較します。 上記のプログラムでは、Innerクラスを静的にして、 Outer.Inner i = new Outer.Inner();でインスタンス化した場合、 " 私は破壊されました! "というOuter.Inner i = new Outer.Inner();


これらの用語は同じ意味で使用されています。 あなたが本当にそれについて賢明であることを望むなら、 "入れ子にされたクラス"を定義して、静的な内部クラスを参照することができます。 コードでは、次のようなものがあります。

public class Outer {
    public class Inner {}

    public static class Nested {}
}

しかし、それは実際に広く受け入れられている定義ではありません。


インスタンスを作成する場合、非静的な内部クラスのインスタンスは、それが定義されている外部クラスのオブジェクトの参照を使用して作成されます。 これは、インスタンスを含むことを意味します。 しかし、静的内部クラスのインスタンスは、外部クラスのオブジェクトの参照ではなく、Outerクラスの参照で作成されます。 これはインスタンスを包含していないことを意味します。

例えば:

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. 静的ネストされたクラス
  2. 非静的なネストされたクラス[内部クラス]

差:

非静的なネストされたクラス[内部クラス]

静的でないネストされたクラスの内部クラスのオブジェクトは、外部クラスのオブジェクト内に存在します。 外部クラスのデータメンバが内部クラスにアクセスできるようにします。 したがって、内部クラスのオブジェクトを作成するには、まず外部クラスのオブジェクトを作成する必要があります。

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

静的ネストされたクラス

内部クラスの静的ネストされたクラスオブジェクトでは、 "静的"という単語はオブジェクトを作成する必要がないため、外部クラスのオブジェクトは必要ありません。

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

xにアクセスする場合は、次の内部メソッドを記述します

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

上記の答えでは、実際の違いが明らかになったとは思いません。

最初に用語を正しく取得する:

  • ネストされたクラスは、ソースコードレベルの別のクラスに含まれるクラスです。
  • 静的修飾子で宣言すると静的です。
  • 非静的なネストされたクラスはインナークラスと呼ばれます。 (私は静的でない入れ子になったクラスに留まります。)

今のところマーティンの答えは正しいです。 しかし、実際の質問は:ネストされたクラスを静的に宣言する目的は何ですか?

一緒に局所的に属している場合、またはネストされたクラスが囲んでいるクラスで排他的に使用されている場合は、 静的なネストされたクラスを使用します 。 静的ネストされたクラスと他のすべてのクラスとの間に意味的な違いはありません。

静的でないネストされたクラスは異なるビーストです。 匿名の内部クラスと同様に、そのような入れ子クラスは実際にはクロージャです。 つまり、周囲のスコープと囲むインスタンスをキャプチャしてアクセス可能にすることを意味します。 おそらくその例がそれを明らかにするでしょう。 コンテナのこのスタブを参照してください:

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

この場合、子アイテムから親コンテナへの参照が必要です。 静的でないネストされたクラスを使うと、これは何らかの作業をしなくても動作します。 Container.thisという構文を使用して、Containerの囲むインスタンスにアクセスできます。

以下のハードコアの説明:

コンパイラが(静的でない)ネストされたクラスのために生成するJavaバイトコードを見ると、さらに明確になる可能性があります。

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

ご覧のとおり、コンパイラはContainer this$0隠しフィールドContainer this$0作成します。 これは、Container型の追加パラメータを持つコンストラクタで設定され、囲むインスタンスを指定します。 このパラメーターはソース内には表示されませんが、コンパイラーはネストされたクラスに対して暗黙的に生成します。

マーティンの例

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

バイトコードのようなものの呼び出しにコンパイルされるでしょう。

new InnerClass(outerObject)

完全性のために:

匿名クラス 、静的でないネストされたクラスの完全な例です。このクラス 、名前が関連付けられておらず、後で参照することもできません。


特定の状況で有用なネストされた静的クラスの使用についての微妙なことがあります。

静的属性は、クラスがそのコンストラクタを介してインスタンス化される前にインスタンス化されますが、ネストされた静的クラスの内部の静的属性は、クラスのコンストラクタが呼び出されるまで、または少なくとも属性が最初に参照されるまで彼らは「最終的」とマークされます。

この例を考えてみましょう。

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

'nested'と 'innerItem'は両方とも 'static final'として宣言されています。 nested.innerItemの設定は、クラスがインスタンス化されるまで(少なくともネストされた静的な項目が最初に参照されるまで)、私が参照している行をコメントしたりコメントを外したりすることでわかります。上記。 同じことは 'outerItem'に当てはまりません。

少なくともこれは私がJava 6.0で見ているものです。


私が思うに、一般的に続いている大会はこれです:

  • トップレベルクラス内の静的クラスネストされたクラスです
  • トップレベルクラス内の非静的クラスは、さらに2つのフォームを持つ内部クラスです。
    • ローカルクラス - メソッドまたはコンストラクタ本体のようなブロックの内部で宣言されたクラス。
    • 匿名クラス - インスタンスが式および文で作成される名前のないクラス

しかし、 覚えておくべき他のはほとんどありません。

  • トップレベルのクラスと静的なネストされたクラスは、静的なネストされたクラスの場合、その外部クラスのプライベートな静的フィールド/メソッドへの静的な参照を行うことができ、逆も同様です。

  • 内部クラスは、外部[親]クラスの囲むインスタンスのインスタンス変数にアクセスできます。 しかし、すべての内部クラスが包含するインスタンスを持っているわけではありません。例えば、静的コンテキスト内の内部クラス(静的イニシャライザブロックで使用される匿名クラスなど)はそうではありません。

  • 匿名クラスは、デフォルトで親クラスを拡張したり、親インタフェースを実装したり、他のクラスを拡張したり、それ以上のインタフェースを実装したりする句はありません。 そう、

    • new YourClass(){}; class [Anonymous] extends YourClass {}
    • new YourInterface(){}; class [Anonymous] implements YourInterface {}ことを意味しclass [Anonymous] implements YourInterface {}

私は、使用する時間と使用する時間を開いたままにしておくという大きな問題があると感じていますか? それは主にあなたが扱っているシナリオに依存しますが、@jrudolphによって与えられた返信を読むことは、あなたが何らかの決定を下すのを助けるかもしれません。


私は、上記の答えのいずれも、ネストされたクラスと静的なネストされたクラスの間の実際の違いをアプリケーション設計の点で説明してくれないと思います。

オーバービュー

ネストされたクラスは非静的でも静的でもよく、それぞれの場合に別のクラス内で定義されたクラスです。 ネストされたクラスは 、ネストされたクラスが他のクラス(囲むだけでなく)によって有益である場合、最上位クラスとして宣言する必要があります。

非静的なネストされたクラスは、 包含するクラスの囲むインスタンスに暗黙的に関連付けられます。つまり、メソッドを呼び出して、囲むインスタンスの変数にアクセスすることができます。 非静的なネストされたクラスの一般的な使用法の1つは、Adapterクラスを定義することです。

静的ネストされたクラス :囲むクラスインスタンスにアクセスすることはできませんし、メソッドを呼び出すので、ネストされたクラスは、囲むクラスのインスタンスへのアクセスを必要としない場合に使用する必要があります。 静的ネストされたクラスの一般的な使用は、外部オブジェクトのコンポーネントを実装することです。

結論

したがって、設計の観点から見た2つの主な違いは、 非静的なネストされたクラスはコンテナクラスのインスタンスにアクセスでき、静的なものはアクセスできないことです。


簡単に言えば、Javaはクロージャを提供しないため、主にネストされたクラスが必要です。

ネストされたクラスは、別のクラスを囲んでいる本体の内部で定義されたクラスです。 静的と非静的の2種類です。

これらは囲みクラスのメンバーとして扱われるためprivate, package, protected, publicの4つのアクセス指定子のいずれかを指定できます。 私たちはこの贅沢をトップレベルのクラスでは持っていません。トップレベルのクラスはpublicに宣言されてpublicかパッケージプライベートにしか宣言されていません。

インナークラス別名非スタッククラスは、プライベート宣言されていてもトップクラスの他のメンバーにアクセスできますが、スタティックネストされたクラスはトップクラスの他のメンバーにアクセスできません。

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

Inner1は静的な内部クラスで、 Inner2は静的でない内部クラスです。 それらの主な違いは、 Inner1オブジェクトを個別に作成できるように、OuterなしでInner2インスタンスを作成することはできません。

Innerクラスはいつ使うのですか?

Class AClass Bが関連し、 Class BClass Aメンバーにアクセスする必要があり、 Class BClass Aのみに関連する状況を考えてみましょう。 インナークラスが絵になります。

内部クラスのインスタンスを作成するには、外部クラスのインスタンスを作成する必要があります。

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

または

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

静的なInnerクラスはいつ使用しますか?

静的な内部クラスは、それが囲むクラス/トップクラスのインスタンスと何の関係もないことを知っているときに定義します。 内部クラスが外部クラスのメソッドやフィールドを使用していない場合は、スペースを無駄にするだけなので静的にしてください。

たとえば、静的ネストされたクラスのオブジェクトを作成するには、次の構文を使用します。

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

静的ネストされたクラスの利点は、クラス/トップクラスを含むオブジェクトが動作する必要がないことです。 これにより、実行時にアプリケーションが作成するオブジェクトの数を減らすことができます。


まず最初に、静的クラスと呼ばれるクラスはありません。内部クラス(静的メンバーと呼ばれ、ネストされたクラスと呼ばれます)を使用する静的修飾子は、外部クラスの静的メンバーであることを示します。 Outerクラスのインスタンス (これはもともとスタティックの利点です)。

Nestedクラスと通常のInnerクラスの違いは次のとおりです。

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

まず、Outerclassをインスタンス化してInnerにアクセスできます。

しかし、Classがネストされている場合、構文は次のようになります。

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

静的キーワードの通常の実装として静的構文を使用します。


以下は例ですstatic nested classinner 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()); 

    }

}




inner-classes