JavaSE - 静的な内部クラス

ced485cbb11e458d81a746890b32cf3f.gif

作者:流川メイプルノックコード

ブログホームページ:流川楓のブログ

コラム:私と一緒にJavaを学ぼう

引用:ハングリーでいて、愚かでいて

良いことをしたいなら、まずツールを研ぎ澄ます必要があります.大手メーカーからのオファーを獲得するための超強力なツールを紹介しましょう-Niuke.com

クリックして無料で登録し、私と一緒に質問をブラッシングしてください  

記事ディレクトリ

1.静的修飾子メンバー変数

2.静的変更メンバーメソッド

3.静的メンバー変数の初期化

4. 内部クラス

インスタンス内部クラス

静的内部クラス

ローカル内部クラス


1.静的修飾子メンバー変数

Java では、静的に変更されたメンバーは、静的メンバーまたはクラス メンバーと呼ばれます. 特定のオブジェクトに属しておらず、すべてのオブジェクトで共有されます. たとえば、生徒のクラスを定義するとき、生徒が受講する教室では、次のように表現する必要があります。クラスの場合、この教室の属性は各生徒オブジェクトに格納する必要はありませんが、すべての生徒で共有する必要があります.この場合、すべてのオブジェクトで共有される静的メンバーを定義する必要があります.

静的に変更されたメンバー変数は、静的メンバー変数と呼ばれます. 静的メンバー変数の最大の特徴は、特定のオブジェクトに属さず、すべてのオブジェクトで共有されることです.

静的メンバー変数の機能:

1. 特定のオブジェクトに属さず、クラスの属性であり、すべてのオブジェクトで共有され、オブジェクトの空間に格納されない

2.オブジェクトまたはクラス名を介してアクセスできますが、通常はクラス名を使用してアクセスすることをお勧めします

3.クラス変数はメソッド領域に格納されます

4. ライフサイクルはクラスの寿命を伴います (つまり、クラスのロードで作成され、クラスのアンロードで破棄されます)。

public class Class {
    private String name;
    private String gender;
    private int age;
    private  static String classRoom = "A123";

    public static void main(String[] args) {
        //静态成员变量可以直接通过类名访问
        System.out.println(Class.classRoom);

        Class c1 = new Class();
        Class c2 = new Class();
        Class c3 = new Class();
        //也可以通过对象访问:但是classRoom是3个对象共享的
        System.out.println(c1.classRoom);
        System.out.println(c2.classRoom);
        System.out.println(c3.classRoom);
    }
}

 上記のコードをデバッグ モードで実行すると、モニター ウィンドウで、静的メンバー変数が特定のオブジェクトに格納されていないことがわかります。

2.静的変更メンバーメソッド

Java では、 static によって変更されたメンバー メソッドをstatic メンバー メソッドと呼びます。これは、オブジェクト固有ではなく、クラスのメソッドです。静的メンバーは通常、静的メソッドを介してアクセスされます

public class Class {
    private String name;
    private String gender;
    private int age;
    private  static String classRoom = "A123";
    public static void setClassRoom(String classRoom) {
        Class.classRoom = classRoom;
    }

    public static String getClassRoom() {
        return classRoom;
    }
}

class TestClass{
    public static void main(String[] args) {
        System.out.println(Class.getClassRoom());
    }

}

出力: A123 

静的メソッドの機能:

1. 特定のオブジェクトに属さず、クラスメソッドである

2.オブジェクトまたはクラス名を介して呼び出すことができます. 静的メソッド名 (...) method , 後者がより推奨されます.

3.静的メソッドで非静的メンバー変数にアクセスすることはできません

コンパイルに失敗しました: 非静的変数です。これは静的コンテキストから参照できません

「Class.this」は静的コンテキストから参照できません

 コンパイルに失敗しました: 静的コンテキストから非静的変数 age を参照できません

非静的フィールド「年齢」は静的コンテキストから参照できません

4.静的メソッドで非静的メソッドを呼び出すことはできません。非静的メソッドにはこのパラメーターがあり、静的メソッドで呼び出すときにこの参照を渡すことができないためです。

 コンパイル エラー: 静的コンテキストから非静的メソッド doClass() を参照できません

3.静的メンバー変数の初期化

注: 通常、静的メンバー変数はコンストラクターで初期化されず、オブジェクト関連のインスタンス プロパティはコンストラクターで初期化されます。

静的メンバー変数の初期化は、インプレース初期化と静的コード ブロック初期化の 2 種類に分けられます。

1. インプレース初期化 インプレース初期化とは、定義時に初期値を直接与えることを指します。

2. 静的コード ブロックの初期化

{} で定義されたコードは、コード ブロックと呼ばれます

コードブロックによって定義される位置とキーワードに応じて、次の 4 つのタイプに分けることができます。

通常のコード ブロック: メソッドで定義されたコード ブロック。

ビルディング ブロックは、インスタンス コード ブロックとも呼ばれます。コンストラクター ブロックは、通常、インスタンス メンバー変数を初期化するために使用されます。

静的ブロック: static を使用して定義されたコードのブロックは、静的コード ブロックと呼ばれます。通常、静的メンバー変数を初期化するために使用されます。

同期されたコード ブロック

class TestClass{
    public TestClass() {
        System.out.println("不带参数的构造方法");
    }

    public static String classes;
    {

        System.out.println("实例代码块");
    }
    static {
        System.out.println("静态代码块");
    }
    public static void main(String[] args) {
        TestClass testClass = new TestClass();
    }

}

 静的コード ブロックが最初に実行され、コードの順序に関係なく、クラスが読み込まれると静的コード ブロックが実行されます。

 再度実行すると、静的コード ブロックは再実行されません。静的コード ブロックで生成されたオブジェクトの数に関係なく、一度だけ実行されます。

予防:

静的コード ブロックで生成されるオブジェクトの数に関係なく、実行されるのは 1 回だけです。

静的メンバー変数はクラスのプロパティであるため、JVM がクラスをロードするときにスペースが開かれ、初期化されます。

クラスに複数の静的コード ブロックが含まれている場合、コードのコンパイル時に、コンパイラは定義された順序に従って順次実行 (マージ) します。

インスタンス コード ブロックは、オブジェクトの作成時にのみ実行されます

4. 内部クラス

記述するために完全な構造が必要な別の部分があり、この内部の完全な構造が外部のものにのみサービスを提供する場合、内部の完全な構造全体で内部クラスを使用するのが最善です。Java では、クラスは別のクラスまたはメソッドの内部で定義できます。前者は内部クラスと呼ばれ、後者は外部クラスと呼ばれます。内部クラスもカプセル化の現れです

public class OutClass{
    class InnerClass{

    }
}
//OutClass是外部类
//InnerClass是内部类

予防:

1. クラス クラス名 {} の中括弧の外に定義されているものは、ファイル内であっても内部クラスとは呼べません

public class A{

}
class B{

}
//A和B是两个独立的类,彼此之前没有关系

2. 内部クラスと外部クラスは同じ Java ソース ファイルを共有しますが、コンパイル後、内部クラスは別のバイトコード ファイルを形成します。

public class Test {
    public static void main(String[] args) {
        System.out.println("hello");
    }
    class Test1{
        public void test(){

        }
    }
}

内部クラス定義の場所に応じて、一般に次の形式に分けることができます。

1. メンバー内部クラス (通常の内部クラス: 静的によって変更されていない静的内部クラス: 静的によって変更されたメンバー内部クラス)

2.ローカル内部クラス(修飾子の話ではありません)、匿名内部クラス(インターフェイスを学習するときに導入されます)

public class OutClass{

    //成员位置定义:未被static修饰--->实例内部类

    public class InnerClass1{
}

    //成员位置定义:被static修饰--->静态内部类

    static class InnerClass2{
}
    public void method(){

    //方法中也可以定义内部类--->局部内部类:几乎不用

        classInnerClass5{
        }
    }
}

注: 内部クラスは、実際には日常の開発ではあまり使用されません. 一部のライブラリのコードを見ていると、多くのことに遭遇する場合があります. 匿名の内部クラスは、日常生活で最も使用されます.

インスタンス内部クラス

つまり、静的によって変更されないメンバーの内部クラス

次の 4 つの質問を見てください。

1. インスタンス内部クラスのオブジェクトを取得するには?

OuterClass.InnerClass innerClass = outerClass.new InnerClass();
public class Test {
    //1:如何获取实例内部类的对象
    OuterClass outerClass = new OuterClass();
    //通过外部类对象的引用来调用内部类,可以把实例内部类当作外部类的一个成员
    OuterClass.InnerClass innerClass = outerClass.new InnerClass();

    //两种写法都可
    OuterClass.InnerClass innerClass2 = new OuterClass().new InnerClass();
}
class OuterClass{

    public int data1;
    int data2;
    public static int data3;
    public void test(){
        System.out.println("OuterClass:test");
    }
    //实例内部类
    class InnerClass{

        public int data4;
        int data5;
        //public static int data6;
        public void func(){
            System.out.println("InnerClass:func");
        }
    }
}

2. なぜエラーが発生するのですか?

 インスタンスの内部クラスに static メンバー変数を含めることはできません。定義する必要がある場合は、final で変更する必要があります。

static は定義されたクラスのメンバーであり、クラスがロードされたときに実行され、内部クラスはオブジェクトの参照を通じて実行される必要があるため、エラーが発生します

 final は定数であり、C の const に似ています。初期化後に変更することはできません。コンパイル後に設定されています。

3. 外側のクラスと内側のクラスの両方に data1 というメンバがありますが、呼び出されたときにどちらが出力されますか?

class OuterClass{

    public int data1 = 1;
    int data2 = 2;
    public static int data3 = 3;
    public void test(){
        System.out.println("OuterClass:test");
    }
    //实例内部类
    class InnerClass{

        public int data1 = 4;
        int data5 = 5;
        public static final int data6 = 6;
        public void func(){
            System.out.println("InnerClass:func");

            System.out.println(data1);
            System.out.println(data2);
            System.out.println(data3);
            //System.out.println(data4);
            System.out.println(data5);
            System.out.println(data6);
        }
    }
}

アクセスは内部クラス自体のメンバーです

4. インナークラスでアウタークラスの同じメンバー変数にアクセスしたい場合は?

 これで問題ありません。または、インスタンスの内部クラスで外部クラスの参照を使用します。

 インスタンスの内部クラスで外部クラスの参照表記を使用します。

System.out.println(OuterClass.this.data1);

予防:

1. 外部クラスの任意のメンバーは、インスタンスの内部クラス メソッドで直接アクセスできます。

2. インスタンス内部クラスの場所は、外部クラス メンバーの場所と同じであるため、public や private などのアクセス修飾子によっても制約されます。

3. インスタンスの内部クラス メソッドで同じ名前のメンバーにアクセスするときは、最初に自分自身にアクセスします。同じ名前で外部クラスのメンバーにアクセスする場合は、次のようにする必要があります。アクセスするのと同じ名前

4.インスタンスの内部クラス オブジェクトは、外部クラス オブジェクトを前提として作成する必要があります。

5. インスタンス内部クラスの非静的メソッドに、外部クラス オブジェクトへの参照が含まれている

6.外側のクラスでは、インスタンスの内側のクラスのメンバーに直接アクセスすることはできません.アクセスする場合は、最初に内側のクラスのオブジェクトを作成する必要があります.

静的内部クラス

静的によって変更された内部メンバー クラスは、静的内部クラスと呼ばれます。

次の 2 つの質問を見てください。

1. 静的な内部クラス オブジェクトを取得するには?

OuterClass2.InnerClass2 innerClass2 = new OuterClass2.InnerClass2();
class OuterClass2{

    public int data1 = 1;
    int data2 = 2;
    public static int data3 = 3;
    public void test(){
        System.out.println("OuterClass:test");
    }
    static class InnerClass2{

        public int data1 = 4;
        int data5 = 5;
        public static int data6 = 6;
        public void func(){
            System.out.println("InnerClass2:func");
        }
    }

    public static void main(String[] args) {
        OuterClass2.InnerClass2 innerClass2 = new OuterClass2.InnerClass2();
    }
}

2. 外部クラスの非静的メンバーは静的内部クラスでアクセスできない 外部クラスの非静的メンバーは、アクセスする外部クラスのオブジェクトへの参照を必要とします。

訪問したい場合:

 予防:

1.静的内部クラスでは、外部クラスの静的メンバーにのみアクセスできます

2. 静的内部クラス オブジェクトを作成する場合、最初に外部クラス オブジェクトを作成する必要はありません。

ローカル内部クラス

メソッド本体または外部クラスの {} で定義されます。この種の内部クラスは、定義されている場所でのみ使用できます。通常はほとんど使用されません。構文形式の簡単な理解は次のとおりです。

public class Test {
    //局部内部类:定义在方法体内部
    // 不能被public、static等访问限定符修饰
    public void method(){
        class InnerClass{

            public void methodInnerClass(){
                System.out.println("hello");
            }

        }
        //只能在该方法体内部使用,其他位置都不能用
        InnerClass innerClass= new InnerClass();
        innerClass.methodInnerClass();
    }

    public static void main(String[] args) {
        //编译失败
        Test.InnerClassinnerClass=null;
    }
}

予防:

1.ローカル内部クラスは、定義されたメソッド本体内でのみ使用できます

2. public や static などの修飾子で変更できない

3. コンパイラには独自の独立したバイトコード ファイルもあり、命名形式は次のとおりです。外部クラス名 $ 内部クラス名.class

 1 つのクラスが 1 つのバイトコード ファイルに対応します。

4.めったに使用しない 

 「この問題の共有はこちらです。ブロガーに 3 つのリンクを提供することを忘れないでください。あなたのサポートが私の創造の最大の原動力です!

ced485cbb11e458d81a746890b32cf3f.gif

 

おすすめ

転載: blog.csdn.net/chenchenchencl/article/details/126179618