English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Java 基礎教程

Java フローコントロール

Java 配列

Java 面向オブジェクト(I)

Java 面向オブジェクト(II)

Java 面向オブジェクト(III)

Java 異常処理

Java リスト(List)

Java キュー(キュー)

Java Map 集合

Java Set 集合

Java 入出(I/O)

Java Reader/Writer

Java その他のトピック

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 種類のアクセス権限があります。

  • デフォルト (即デフォルト、何も書かない場合): 同一パッケージ内で可见、修飾子を使用しません。使用例:クラス、インターフェース、変数、メソッド。

  • プライベート : 同一クラス内で可见です。使用例:変数、メソッド。 注意:クラス(外部クラス)には修飾子を付けられません

  • public : すべてのクラスに対して可见です。使用例:クラス、インターフェース、変数、メソッド

  • protected : 同一パッケージ内のクラスおよびすべてのサブクラスに対して可见です。使用例:変数、メソッド。 注意:クラス(外部クラス)には修飾子を付けられません

以下の表を使用してアクセス権限を説明できます:

アクセス制御

修飾子現在のクラス同一パッケージ内子孫クラス(同一パッケージ)子孫クラス(異なるパッケージ)他のパッケージ
publicYYYYY
protectedYYYY/N(説明N
デフォルトYYYNN
プライベートYNNNN

デフォルトアクセス修飾子-修飾子を使用しない

デフォルトアクセス修飾子で宣言された変数やメソッドは、同じパッケージ内のクラスに対して可见です。インターフェース内の変数は暗黙的にpublic static finalとして宣言され、インターフェース内のメソッドはデフォルトではpublicアクセス権限です。

以下の例のように、変数やメソッドの宣言には修飾子を使用しなくても構いません。

package defaultPackage;
class Logger {
    void message(){
        System.out.println("This is a message");
    }
}

ここでは、Loggerクラスはデフォルトのアクセス修飾子を持っています。このクラスはdefaultPackageパッケージに属するすべてのクラスに対して可见です。しかし、defaultPackageの外の別のクラスでLoggerクラスを使用しようとすると、コンパイルエラーが発生します。

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

プライベートアクセス修飾子は最も厳格なアクセスレベルであり、したがって宣言されたものは プライベート のメソッド、変数、およびコンストラクタは、所属クラスのみがアクセスできます。また、クラスやインターフェースはプライベートアクセス修飾子として宣言できません。 プライベート

プライベートアクセスタイプの変数は、外部クラスからアクセスするにはクラス内の公共のgetterメソッドを通じてのみアクセスできます。

プライベートアクセス修飾子の使用は、クラスの実装の詳細を隠すために主に用いられ、クラスのデータを保護するために用いられます。

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

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

例では、Loggerクラスのformat変数はプライベートな変数であり、他のクラスはその値を直接取得したり設定したりできません。他のクラスがこの変数を操作できるようにするために、getFormat()(formatの値を返す)とsetFormat(String)(formatの値を設定する)という2つのpublicメソッドを定義しました。

共有アクセス修飾子-public

publicとして宣言されたクラス、メソッド、コンストラクタ、インターフェースは他のすべてのクラスによってアクセスできます。

異なるパッケージに分布している相互にアクセスするいくつかのpublicクラスがある場合、それぞれのpublicクラスが属するパッケージをインポートする必要があります。クラスの継承性により、クラスのすべての共有メソッドや変数はその子クラスによって継承されます。

以下の関数は共有(public)アクセス制御を使用しています:

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

Javaプログラムのmain()メソッドは共有(public)に設定しなければなりません。さもなければ、Javaインタープリタはそのクラスを実行できません。

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

protectedは以下の2つのポイントから分析・説明する必要があります:

  • 子クラスと基類は同じパッケージにあります:protectedとして宣言された変数、メソッド、コンストラクタは同じパッケージの他のすべてのクラスによってアクセスできます;

  • 子クラスと基類は同じパッケージではありません:したがって、子クラスでは、子クラスのインスタンスは基類から継承したprotectedメソッドにアクセスできますが、基類のインスタンスのprotectedメソッドにはアクセスできません。

protectedはデータメンバー、コンストラクタ、メンバメソッドを修飾できます。protectedはクラス(内部クラスを除く)を修飾できません。

インターフェースおよびインターフェースのメンバ変数やメンバメソッドはprotectedとして宣言できません。

子クラスはprotected修飾子で宣言されたメソッドや変数にアクセスできます。これにより、関連のないクラスがこれらのメソッドや変数を使用することを防ぐことができます。

以下の親クラスはprotectedアクセス修飾子を使用しており、子クラスは親クラスのopenSpeaker()メソッドをオーバーライドしています。

class AudioPlayer {
   protected boolean openSpeaker(Speaker sp) {}}
      // 実現詳細
   }
}
 
class StreamingAudioPlayer extends AudioPlayer {
   protected boolean openSpeaker(Speaker sp) {}}
      // 実現詳細
   }
}

openSpeaker()メソッドをprivateとして宣言すると、AudioPlayer以外のクラスはそのメソッドにアクセスできません。

openSpeaker()をpublicとして宣言すると、すべてのクラスがそのメソッドにアクセスできます。

そのメソッドが自身のクラスのサブクラスに対してのみアクセス可能になるように、そのメソッドをprotectedとして宣言します。

protectedは、最も理解が難しいJavaクラスメンバーのアクセス権修飾語の一つです。

アクセス制御と継承

以下のメソッド継承のルールに注意してください:

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

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

  • 親クラスでprivateとして宣言されたメソッドは、継承できません。

非アクセス修飾子

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

static修飾子は、クラスメソッドとクラス変数を修飾するために使用されます。

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

abstract修飾子は、抽象クラスと抽象メソッドを生成するために使用されます。

synchronizedおよびvolatile修飾子は、主にスレッドのプログラミングに使用されます。

static修飾子

  • 静的変数:

    staticキーワードは、オブジェクトに依存しない静的変数を宣言するために使用されます。どれだけのクラス例がシリアライズされるにしても、その静的変数はコピーが1つだけです。 静的変数はまた、クラス変数とも呼ばれます。ローカル変数はstatic変数として宣言することはできません。

  • 静的メソッド:

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

類変数とメソッドのアクセスは直接使用できます。 classname.variablename および classname.methodname 的方式訪問。

以下例示,static修飾子用於創建類方法和類變數。

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("从 " +
      InstanceCounter.getCount() + "個のインスタンスから始めて");
      for (int i = 0; i < 500; ++i){
         new InstanceCounter();
          }
      System.out.println("Created " +
      InstanceCounter.getCount() + " instances");
   }
}

以下の例の実行結果は次の通りです:

0個のインスタンスから始めて
作成 500 インスタンス

final修飾子

final変数:

finalは「最後の、最終の」意味を持ち、変数が一度値が設定されると、それ以降再設定できません。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メソッドを宣言する主な目的は、その内容が変更されないようにすることです。

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

public class Test{
    public final void changeName(){
       // メソッド体
    }
}

finalクラス

finalクラスは継承できません。finalクラスのどの特性も継承できるクラスはありません。

public final class Test {
   // クラス体
}

abstract修飾子

抽象クラス:

抽象クラスはオブジェクトの例示には使用できません。抽象クラスを宣言する唯一の目的は、将来このクラスを拡張することです。

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

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

abstract class Caravan{
   private double price;
   private String model;
   private String year;
   public abstract void goFast(); //抽象メソッド
   public abstract void changeColor();
}

抽象メソッド

抽象メソッドは、具体的な実装を持たないメソッドであり、その具体的な実装はサブクラスで提供されます。

抽象メソッドは final または static として宣言することはできません。

抽象クラスを継承するすべてのサブクラスは、親クラスのすべての抽象メソッドを実装する必要があります。ただし、そのサブクラスが抽象クラスでもあれば、例外です。

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

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

public abstract class SuperClass{
    abstract void m(); //抽象メソッド
}
 
class SubClass extends SuperClass{
     //抽象メソッドを実装します
      void m(){
          .........
      }
}

synchronized 修飾子

synchronized キーワードで宣言されたメソッドは、一度に一つのスレッドしかアクセスできない。synchronized 修飾子は、4つのアクセス修飾子に適用できます。

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

transient 修飾子

シリアライズされたオブジェクトが transient 修飾された変数を含む場合、Java仮想機(JVM)はその特定の変数をスキップします。

この修飾子は、クラスと変数のデータ型を事前に処理するために変数の定義文に含まれています。

public transient int limit = 55;   // 持久化されません
public int b; // 持久化

volatile 修飾子

volatile 修飾されたメンバ変数は、各回のスレッドアクセス時に必ず共有メモリからメンバ変数の値を再読み込みします。また、メンバ変数が変更された場合、変更された値を共有メモリに強制的に書き戻します。そのため、どんな時でも、異なるスレッドが同じメンバ変数の同じ値を見ることになります。

volatileオブジェクトリファレンスがnullである可能性があります。

public class MyRunnable implements Runnable
{
    private volatile boolean active;
    public void run()
    {
        active = true;
        while (active) // 第1行
        {
            // コード
        }
    }
    public void stop()
    {
        active = false; // 第2行
    }
}

通常、run()メソッド(Runnableで開始されたスレッド)を呼び出すスレッドと、stop()メソッドを呼び出すスレッドが異なる場合があります。 もし 第1行 中のバッファーのactive値が使用されている場合、 第2行 のactive値がfalseの場合、ループは停止しません。

しかし、このコードでは、volatile修飾子でactiveを使用しているため、このループは停止します。