Java修飾子


Java 言語には多くの修飾子があり、主に次の 2 つのカテゴリに分類されます:

  • アクセス修飾子

  • 非アクセス修飾子

修飾子はクラス、メソッド、または変数を定義するために使用され、通常は配置されます。という声明。次の例を使用して説明します。

public class className {
   // ...
}
private boolean myFlag;
static final double weeks = 9.5;
protected static final int BOXWIDTH = 42;
public static void main(String[] arguments) {
   // 方法体
}

アクセス制御修飾子

Java では、アクセス制御修飾子を使用して、クラス、変数、メソッド、およびコンストラクターへのアクセスを保護できます。 Java は 4 つの異なるアクセス権をサポートしています。

Default (default とも呼ばれます) は、修飾子なしで同じパッケージ内に表示されます。

Private。 private 修飾子で指定され、同じクラス内で表示されます。

Public、public修飾子で指定され、すべてのクラスに表示されます。

Protected、protected修飾子で指定され、同じパッケージ内のクラスとすべてのサブクラスに表示されます。

デフォルトのアクセス修飾子 - キーワードを使用しない

デフォルトのアクセス修飾子で宣言された変数とメソッドは、同じパッケージ内のクラスから参照できます。インターフェイス内の変数は暗黙的に public static Final として宣言され、インターフェイス内のメソッドのアクセス権はデフォルトで public になります。

例:

以下の例に示すように、変数とメソッドは修飾子なしで宣言できます。

String version = "1.5.1";
boolean processOrder() {
   return true;
}

プライベート アクセス修飾子 - プライベート

プライベート アクセス修飾子は最も制限的なアクセス レベルであるため、プライベートとして宣言されたメソッド、変数、およびコンストラクターには、それらが属するクラスのみがアクセスでき、クラスとインターフェイスをプライベートとして宣言することはできません。 。

プライベート アクセス型として宣言された変数には、クラス内のパブリック getter メソッドを介して外部クラスからのみアクセスできます。

Private アクセス修飾子の使用は、主にクラスの実装の詳細を隠し、クラスのデータを保護するために使用されます。

次のクラスはプライベート アクセス修飾子を使用します:

public class Logger {
   private String format;
   public String getFormat() {
      return this.format;
   }
   public void setFormat(String format) {
      this.format = format;
   }
}

この例では、Logger クラスのフォーマット変数はプライベート変数であるため、他のクラスは変数の値を直接取得および設定できません。他のクラスがこの変数を操作できるようにするために、2 つのパブリック メソッドが定義されています: getFormat() (format の値を返す) と setFormat(String) (format の値を設定する)

パブリック アクセス修飾子 - public

が宣言されていますpublic クラス、メソッド、コンストラクター、およびインターフェイスには、他のクラスからアクセスできます。

相互にアクセスする複数のパブリック クラスが異なるパッケージで配布されている場合は、対応するパブリック クラスが配置されているパッケージをインポートする必要があります。クラスの継承により、クラスのすべてのパブリック メソッドと変数はそのサブクラスに継承できます。

次の関数はパブリック アクセス制御を使用します:

public static void main(String[] arguments) {
   // ...
}

Java プログラムの main() メソッドは public に設定する必要があります。そうしないと、Java インタープリターはクラスを実行できません。

保護されたアクセス修飾子で保護された

保護として宣言された変数、メソッド、およびコンストラクターは、同じパッケージ内の他のクラスからアクセスでき、また、異なるパッケージ内のサブクラスからもアクセスできます。

保護されたアクセス修飾子はクラスとインターフェイスを変更できません。メソッドとメンバー変数は保護されたものとして宣言できますが、インターフェイスのメンバー変数やメンバー メソッドは保護されたものとして宣言できません。

サブクラスは、Protected 修飾子によって宣言されたメソッドと変数にアクセスできるため、無関係なクラスがこれらのメソッドや変数を使用しないように保護されます。

次の親クラスは protected アクセス修飾子を使用し、サブクラスは親クラスの openSpeaker() メソッドをオーバーロードします。

class AudioPlayer {
   protected boolean openSpeaker(Speaker sp) {
      // 实现细节
   }
}

class StreamingAudioPlayer {
   boolean openSpeaker(Speaker sp) {
      // 实现细节
   }
}

openSpeaker() メソッドが private として宣言されている場合、AudioPlayer 以外のクラスはこのメソッドにアクセスできません。 openSpeaker() が public として宣言されている場合、すべてのクラスがこのメソッドにアクセスできます。メソッドをそのクラスのサブクラスにのみ表示したい場合は、メソッドを保護として宣言します。

アクセス制御と継承

メソッド継承に関する次のルールに注意してください:

  • 親クラスで public として宣言されたメソッドは、子クラスでも public である必要があります。

  • 親クラスで protected として宣言されたメソッドは、サブクラスで protected または public として宣言されます。非公開と宣言することはできません。

  • 親クラスでプライベートとして宣言されたメソッドは継承できません。


非アクセス修飾子

他の機能を実装するために、Java は多くの非アクセス修飾子も提供します。

静的修飾子。クラスメソッドとクラス変数の作成に使用されます。

final 修飾子は、クラス、メソッド、変数を変更するために使用されます。final によって変更されたクラスは継承できません。変更されたメソッドは継承されたクラスによって再定義できません。また、変更された変数は定数であるため変更できません。

抽象修飾子。抽象クラスと抽象メソッドの作成に使用されます。

同期修飾子と揮発性修飾子は主にスレッド プログラミングに使用されます。

Static 修飾子

  • Static 変数:

    Static キーワードは、オブジェクトから独立した静的変数を宣言するために使用されます。クラスがインスタンス化するオブジェクトの数に関係なく、静的変数のコピーは 1 つだけ存在します。 静的変数はクラス変数とも呼ばれます。ローカル変数は静的変数として宣言できません。

  • 静的メソッド:

    静的キーワードは、オブジェクトから独立した静的メソッドを宣言するために使用されます。静的メソッドでは、クラスの非静的変数を使用できません。静的メソッドはパラメーター リストからデータを取得し、データを計算します。

クラス変数とメソッドへのアクセスは、classname.variablename と classname.methodname を使用して直接アクセスできます。

以下の例に示すように、クラスメソッドとクラス変数を作成するために静的修飾子が使用されます。

public class InstanceCounter {
   private static int numInstances = 0;
   protected static int getCount() {
      return numInstances;
   }

   private static void addInstance() {
      numInstances++;
   }

   InstanceCounter() {
      InstanceCounter.addInstance();
   }

   public static void main(String[] arguments) {
      System.out.println("Starting with " +
      InstanceCounter.getCount() + " instances");
      for (int i = 0; i < 500; ++i){
         new InstanceCounter();
          }
      System.out.println("Created " +
      InstanceCounter.getCount() + " instances");
   }
}

上記の実行例と編集結果は次のとおりです:

Started with 0 instances
Created 500 instances

Final 修飾子

Final 変数:

Final 変数は明示的に初期化でき、初期化できるのは 1 回のみです。 Final として宣言されたオブジェクトへの参照は、別のオブジェクトを指すことはできません。ただし、最終オブジェクトのデータは変更できます。つまり、最終オブジェクトの参照は変更できませんが、内部の値は変更できます。

Final 修飾子は通常、クラス定数を作成するために static 修飾子と一緒に使用されます。

例:

public class Test{
  final int value = 10;
  // 下面是声明常量的实例
  public static final int BOXWIDTH = 6;
  static final String TITLE = "Manager";

  public void changeValue(){
     value = 12; //将输出一个错误
  }
}

Finalメソッド

クラス内のFinalメソッドはサブクラスに継承できますが、サブクラスによって変更することはできません。

最終メソッドを宣言する主な目的は、メソッドの内容が変更されるのを防ぐことです。

以下のように、final修飾子を使用してメソッドを宣言します。

public class Test{
    public final void changeName(){
       // 方法体
    }
}

最終クラス

最終クラスは継承できません。どのクラスも最終クラスの特性を継承できません。

インスタンス:

public final class Test {
   // 类体
}

抽象修飾子

抽象クラス:

抽象クラスを宣言する唯一の目的は、将来クラスを拡張することです。

クラスをabstractとfinalで同時に変更することはできません。クラスに抽象メソッドが含まれる場合、クラスは抽象クラスとして宣言する必要があります。そうしないと、コンパイル エラーが発生します。

抽象クラスには、抽象メソッドと非抽象メソッドを含めることができます。

例:

abstract class Caravan{
   private double price;
   private String model;
   private String year;
   public abstract void goFast(); //抽象方法
   public abstract void changeColor();
}

抽象メソッド

抽象メソッドは、実装を持たないメソッドであり、メソッドの具体的な実装はサブクラスによって提供されます。抽象メソッドは、final および strict として宣言できません。

抽象クラスを継承するサブクラスは、そのサブクラスが抽象クラスでない限り、親クラスのすべての抽象メソッドを実装する必要があります。

クラスに複数の抽象メソッドが含まれる場合、クラスは抽象クラスとして宣言する必要があります。抽象クラスには抽象メソッドを含める必要はありません。

抽象メソッドの宣言はセミコロンで終わります。例: public abstract sample();

例:

public abstract class SuperClass{
    abstract void m(); //抽象方法
}
 
class SubClass extends SuperClass{
     //实现抽象方法
      void m(){
          .........
      }
}

Synchronized 修飾子

Synchronized キーワードで宣言されたメソッドには、同時に 1 つのスレッドのみアクセスできます。 。 Synchronized 修飾子は 4 つのアクセス修飾子に適用できます。

例:

public synchronized void showDetails(){
.......
}

Transient 修飾子

シリアル化されたオブジェクトに、transient によって変更されたインスタンス変数が含まれている場合、Java 仮想マシン (JVM) はその特定の変数をスキップします。

この修飾子は変数を定義するステートメントに含まれており、クラスと変数のデータ型を前処理するために使用されます。

例:

public transient int limit = 55;   // will not persist
public int b; // will persist

Volatile 修飾子

Volatile で変更されたメンバー変数は、スレッドによってアクセスされるたびに共有メモリからメンバー変数の値を強制的に再読み取りします。さらに、メンバー変数が変更されると、スレッドは変更された値を共有メモリに書き戻すことを強制されます。このようにして、いつでも 2 つの異なるスレッドがメンバー変数の同じ値を参照します。

揮発性オブジェクト参照は null になる可能性があります。

例:

public class MyRunnable implements Runnable
{
    private volatile boolean active;
    public void run()
    {
        active = true;
        while (active) // 第一行
        {
            // 代码
        }
    }
    public void stop()
    {
        active = false; // 第二行
    }
}

通常、run() メソッドは 1 つのスレッド (Runnable によって開始されたスレッド) で呼び出され、stop() メソッドは別のスレッドで呼び出されます。 1行目のバッファのアクティブ値が使用されている場合、2行目のアクティブ値がfalseの場合、ループは停止しません。

しかし、上記のコードでは volatile を使用して active を変更しているため、ループは停止します。