Java での static キーワードと内部クラスの使用方法の詳細な説明

WBOY
リリース: 2022-08-17 20:27:56
転載
1572 人が閲覧しました

この記事では、java に関する関連知識を提供し、Java での静的キーワードと内部クラスの使用方法を詳しく紹介します。記事内のサンプル コードは詳細に説明されています。見てみましょう。皆さんもぜひご協力ください。

Java での static キーワードと内部クラスの使用方法の詳細な説明

推奨学習: 「java ビデオ チュートリアル

1. static キーワード

Java では、メンバーが変更されましたby static は静的メンバーまたはクラスメンバーと呼ばれ、特定のオブジェクトに属さず、すべてのオブジェクトで共有されます。

1. 静的に変更されたメンバー変数

静的に変更されたメンバー変数は静的メンバー変数と呼ばれます

[静的メンバー変数の特性]:

  • 特定のオブジェクトに属しません。クラスの属性です。すべてのオブジェクトによって共有され、オブジェクトの空間に格納されません。
  • オブジェクト参照を通じてアクセスできます。 (推奨されません))、クラス名を使用してアクセスすることもできますが、通常はクラス名を使用してアクセスすることをお勧めします。
  • クラス変数はメソッド領域に格納されます
  • ライフサイクルクラスの存続期間を伴います (つまり、クラスのロードによって変更され、クラスがアンロードされると作成および破棄されます)
  • #
    public class Student{
        public String name;
        public String gender;
        public int age;
        public double score;
        public static String classRoom = "rj2104";
    
        public Student(String name, String gender, int age, double score) {
            this.name = name;
            this.gender = gender;
            this.age = age;
            this.score = score;
        }
    
        // ...
        public static void main(String[] args) {
            // 静态成员变量可以直接通过类名访问
            System.out.println(Student.classRoom);
            
            Student s1 = new Student("Li leilei", "男", 18, 3.8);
            Student s2 = new Student("Han MeiMei", "女", 19, 4.0);
            Student s3 = new Student("Jim", "男", 18, 2.6);
            
            // 也可以通过对象访问:但是classRoom是三个对象共享的
            System.out.println(s1.classRoom);
            System.out.println(s2.classRoom);
            System.out.println(s3.classRoom);
    
        }
    }
    ログイン後にコピー

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

一般に、クラスのデータ メンバーはプライベートに設定され、メンバーのメソッドはパブリックに設定されます。

Java では、静的によって変更されたメンバー メソッドは静的メンバー メソッドと呼ばれます。クラスであり、オブジェクトに固有のものではありません。

静的メンバーには、通常、静的メソッドを通じてアクセスします。

public class Student2{
    // ...
    private static String classRoom = "rj2104";
    // ...
    public static String getClassRoom(){
        return classRoom;
    }
}

class TestStudent {
    public static void main(String[] args) {
        System.out.println(Student2.getClassRoom());
    }
}
ログイン後にコピー

[静的メソッドの特性]:

    特定のオブジェクトに属しません。クラス メソッドです。
  • オブジェクトを通じて呼び出すことも、クラス名。静的メソッド名 (...) を呼び出す場合は、後者を使用することをお勧めします。
  • 静的メソッド内の非静的メンバー変数および非静的メンバー メソッドにはアクセスできません。非静的メソッドにはデフォルトでこのパラメータがありますが、静的メソッドでは静的メソッドで新しいオブジェクトが作成され、そのオブジェクトがオブジェクト参照を通じてアクセスされる場合を除き、メソッドの呼び出し時にこの参照を渡すことはできません
  • 静的メソッドをオーバーライドしたり、ポリモーフィズムの実装に使用したりすることはできません

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

静的メンバー変数は通常、 では初期化されません。コンストラクターで初期化されるのは、オブジェクトに関連するインスタンス属性です

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

インプレース初期化: 定義時に初期値を直接指定します

public class Student2{
    // ...
    //就地初始化
    private static String classRoom = "rj2104";
    //...
}
ログイン後にコピー

静的コード ブロックを使用して初期化を完了します

public class Student2{
    // ...
    private static String classRoom;
    
    //静态代码块初始化
    static {
        classRoom = "rj2104";
    }

    // ...
}
ログイン後にコピー

2. 内部クラス

In Java では、別のクラスやメソッドの中にクラスを定義することができ、前者を内部クラス、後者を外部クラスと呼びます。内部クラスもカプセル化の現れです。

内部クラスと外部クラスは同じ Java ソース ファイルを共有しますが、コンパイル後、内部クラスは別のバイトコード ファイルを形成します。通常、バイトコード ファイル名は次のようになります: 外部クラス名 $ 内部クラス名.class

public class OutClass {
    class InnerClass{
    }
}
// OutClass是外部类
// InnerClass是内部类
ログイン後にコピー

内部クラス定義は、その位置に応じて、一般に次の形式に分けられます:

1. メンバ内部クラス (通常の内部クラス) )

インスタンス内部クラス:静的に変更されていないメンバーの内部クラス

静的内部クラス:静的に変更されたメンバーの内部クラス

2.ローカル内部クラス

3. 匿名内部クラス

#1. インスタンス内部クラス

# は、静的に変更されていないメンバー内部クラスです。

[注意事項]:

    外部クラスのメンバーは、インスタンスの内部クラス メソッドで直接アクセスできます。
  • インスタンス内部に静的オブジェクトを含めることはできません。クラス メンバー変数; 定義する必要がある場合は、静的 Final によって変更された静的定数のみにすることができます。定数はプログラムのコンパイル時に決定されます。
  • インスタンスの内部クラスの場所は、次と同じです。外部クラスのメンバーの場所。パブリック、プライベート、その他のアクセス修飾子の影響も受けます。
  • インスタンスの内部クラス オブジェクトは、作成する前にまず外部クラス オブジェクトを持つ必要があります。
  • 非静的インスタンスの内部クラスのメソッドには、デフォルトのメソッドが含まれています。 外部クラスのオブジェクトへの参照と、自身のインスタンスの内部クラスのオブジェクトへの参照が含まれています。
  • インスタンスの内部クラス メソッドで同じ名前のメンバーにアクセスする場合、同じ名前の外部クラスのメンバーにアクセスしたい場合は、次の手順を実行する必要があります: 外部クラス名.this.同じ名前のメンバーは、
  • 外部クラスにアクセスするために使用されます。インスタンスの内部クラスのメンバーには直接アクセスできないため、アクセスしたい場合は、まず内部クラスのオブジェクトを作成する必要があります。
  • public class OutClass {
        private int a;
        static int b;
        int c;
    
        public void methodA() {
            a = 10;
            System.out.println(a);
        }
    
        public static void methodB() {
            System.out.println(b);
        }
    
        // 实例内部类:未被static修饰
        class InnerClass {
            int c;
    //实例内部类当中 不能有静态的成员变量. 非要定义,那么只能是被static final修饰的
            public static final int d = 6;
    
            public void methodInner() {
    // 在实例内部类中可以直接访问外部类中:任意访问限定符修饰的成员
                a = 100;
                b = 200;
                methodA();
                methodB();
                System.out.println(d);
    // 如果外部类和实例内部类中具有相同名称成员时,优先访问的是内部类自己的
                c = 300;
                System.out.println(c);
    // 如果要访问外部类同名成员时候,必须:外部类名称.this.同名成员名字
                OutClass.this.c = 400;
                System.out.println(OutClass.this.c);
            }
        }
    
        public static void main(String[] args) {
    // 外部类:对象创建 以及 成员访问
            OutClass outClass = new OutClass();
    
            System.out.println(outClass.a);
            System.out.println(outClass.b);
            System.out.println(outClass.c);
            outClass.methodA();
            outClass.methodB();
            System.out.println("=============实例内部类的访问=============");
    // 要访问实例内部类中成员,必须要创建实例内部类的对象
    // 而普通内部类定义与外部类成员定义位置相同,因此创建实例内部类对象时必须借助外部类
    // 创建实例内部类对象
            OutClass.InnerClass innerClass1 = new OutClass().new InnerClass();
            innerClass1.methodInner();
    // 上述语法比较怪异,也可以先将外部类对象先创建出来,然后再创建实例内部类对象
            OutClass.InnerClass innerClass2 = outClass.new InnerClass();
            innerClass2.methodInner();
        }
    }
    ログイン後にコピー
2. 静的内部クラス

静的に変更された内部メンバークラスを静的内部クラスと呼びます。 ,

[注意]:

静的内部クラスでは、外部クラスの新しいオブジェクトを内部クラスで作成しない限り、外部クラスの静的メンバーにのみアクセスできます。外部クラスのオブジェクト 非静的メンバーにアクセスするための参照。

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

public class OuterClass2 {
    public int data1 = 1;
    int data2 = 2;
    public static int data3 = 3;

    public void test() {
        System.out.println("out::test()");
    }

    // 静态内部类:被static修饰的成员内部类
    static class InnerClass2 {
        public int data4 = 4;
        int data5 = 5;
        public static int data6 = 6;

        public void func() {
            System.out.println("out::func()");

            //test();
            // 编译失败,在静态内部类中不能直接访问外部类中的非静态成员
            //System.out.println(data1);
            //System.out.println(data2);

            //外部类的非静态成员,需要通过外部类的对象的引用才能访问。
            OuterClass2 outerClass = new OuterClass2();
            System.out.println(outerClass.data1);
            System.out.println(outerClass.data2);
            outerClass.test();

            // 在静态内部类中只能访问外部类的静态成员
            System.out.println(data3);
            System.out.println(data4);
            System.out.println(data5);
            System.out.println(data5);
            System.out.println(data6);

        }
    }
    public static void main(String[] args) {
        // 静态内部类对象创建 和 成员访问
        OuterClass2.InnerClass2 innerClass2 = new OuterClass2.InnerClass2();
        innerClass2.func();

    }
}
ログイン後にコピー

3.ローカル内部クラス

はメソッド本体で定義されます。外部クラスまたは { }。通常、使用されることは非常にまれです。 ######【予防】###

局部内部类只能在所定义的方法体内部使用

不能被public、static等修饰符修饰

局部内部类生成的字节码文件稍有区别:外部类名字$数字内部类名字.class

ppublic class OutClass {
    int a = 10;
    
    public void method(){
        int b = 10;
        // 局部内部类:定义在方法体内部
        // 不能被public、static等访问限定符修饰
        class InnerClass{
            public void methodInnerClass(){
                System.out.println(a);
                System.out.println(b);
            }
        }
        // 只能在该方法体内部使用,其他位置都不能用
        InnerClass innerClass = new InnerClass();
        innerClass.methodInnerClass();
    }
    
    public static void main(String[] args) {
    // OutClass.InnerClass innerClass = null; 编译失败
    }
}
ログイン後にコピー

4. 匿名内部类

匿名内部类,就是没有名字的一种嵌套类

匿名内部类形成的字节码文件文件名为:外部类名字$数字.class

4.1 使用匿名内部的好处与演示

在实际开发中,我们会遇到下面的情况:

一个接口/类的方法的某个执行过程在程序中只会执行一次,但为了使用它,我们需要创建它的实现类/子类去实现/重写方法。

代码中为了这一次的使用去创建一个类,未免太过麻烦,此时就可以使用匿名内部类来解决这个问题

首先来看我们正常的实现逻辑,假设有一个接口,接口当中只有一个方法

public interface Interface {
    void show();
}
ログイン後にコピー

为了使用该接口的show方法,我们需要去创建一个实现类,重写show方法的具体实现

public class Test implements Interface{
    @Override
    public void show() {
        System.out.println("只执行一次show()");
    }
}

public class Main {
    public static void main(String[] args) {
        Test test = new Test();
        test.show();
    }
}
ログイン後にコピー

如果实现类Test在程序中只使用一次,那么为了这一次的使用去创建一个类太过繁琐,这种情况下就可以用匿名内部类来实现,无需创建新的类,减少代码冗余,

看下面代码:

class Main {
    public static void main(String[] args) {
        //写法一
        Interface in = new Interface() {
            @Override
            public void show() {
                System.out.println("匿名内部类中重写show()");
            }
        };
        //调用接口方法
        in.show();
        
        //写法二
        new Interface() {
            @Override
            public void show() {
                System.out.println("匿名内部类中重写show()");
            }
        }.show();//调用接口方法
    }
}
ログイン後にコピー

4.2 匿名内部类的定义格式和使用

定义格式1:

接口名称 引用名 = new 接口名称() {
// 覆盖重写所有抽象方法
};

引用名.方法调用

定义格式2:

new 接口名称() {
// 覆盖重写所有抽象方法
}.方法调用;

对格式“new 接口名称() {…}”的理解:

new代表创建一个新的对象对象

接口名称就是匿名内部类需要实现哪个接口

{…}中是匿名内部类的内容

【注意事项】:

  • 匿名内部类,在【创建对象】的时候,只能使用唯一 一次。
  • 匿名对象,在【调用方法】的时候,只能调用唯一 一次。
  • 匿名内部类是省略了【实现类/子类名称】,但是匿名对象是省略了【对象名称】
  • 匿名内部类可以用在具体类、抽象类、接口上,且对方法个数没有要求。
public class Class {
    public void show(String s){
        System.out.println("Class::show()");
    }
}

public abstract class AbstractClass {
    abstract void show(String s);
}

public interface Interface {
    void show(String s);
}

public class TestDome {
    public static void main(String[] args) {

        //重写普通类的方法
        new Class(){
            @Override
            public void show(String s) {
                System.out.println(s);
            }
        }.show("普通类");

        //重写抽象类的抽象方法
        new AbstractClass(){
            @Override
            void show(String s) {
                System.out.println(s);
            }
        }.show("抽象类");

        //实现接口的抽象方法
        new Interface(){
            @Override
            public void show(String s) {
                System.out.println(s);
            }
        }.show("接口");

    }
}
ログイン後にコピー

执行结果:

推荐学习:《java视频教程

以上がJava での static キーワードと内部クラスの使用方法の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:jb51.net
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
関連するチュートリアル
人気のおすすめ
最新のコース
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!