Java 修飾子
Java言語は多くの修飾子を提供しており、主に以下の2種類に分けられます:
- アクセス修飾子
- 非アクセス修飾子
修飾子はクラス、メソッド、変数を定義するために使用され、通常は文の先頭に置かれます。次の例で説明します:
アクセス制御修飾子
Javaでは、アクセス制御修飾子を使用して、クラス、変数、メソッド、コンストラクタへのアクセスを保護できます。Javaは4種類の異なるアクセス権限をサポートしています。
-
default(デフォルト、何も書かない): 同じパッケージ内で可視。修飾子を使用しない。使用対象: クラス、インターフェース、変数、メソッド。
-
private: 同じクラス内で可視。使用対象: 変数、メソッド。注意: クラス(外部クラス)を修飾することはできません。
-
public: すべてのクラスに可視。使用対象: クラス、インターフェース、変数、メソッド
-
protected: 同じパッケージ内のクラスとすべてのサブクラスに可視。使用対象: 変数、メソッド。注意: クラス(外部クラス)を修飾することはできません。。
以下の表でアクセス権限を説明できます:
| 修飾子 | 現在のクラス | 同じパッケージ内 | サブクラス(同じパッケージ) | サブクラス(異なるパッケージ) | 他のパッケージ |
|---|---|---|---|---|---|
public |
Y | Y | Y | Y | Y |
protected |
Y | Y | Y | Y/N(説明) | N |
default |
Y | Y | Y | N | N |
private |
Y | N | N | N | N |
デフォルトアクセス修飾子 - キーワードを使用しない
クラス、変数、メソッド、コンストラクタの定義でアクセス修飾子を指定しない場合、それらはデフォルトでデフォルトアクセス修飾子を持ちます。
デフォルトアクセス修飾子のアクセスレベルはパッケージレベルであり、同じパッケージ内の他のクラスからのみアクセスできます。
次の例のように、変数とメソッドの宣言では修飾子を使用しなくてもかまいません。
例
上記の例では、MyClass クラスとそのメンバー変数 x およびメソッド display() はすべてデフォルトアクセス修飾子を使用して定義されています。MyOtherClass クラスは同じパッケージ内にあるため、MyClass クラスとそのメンバー変数・メソッドにアクセスできます。
プライベートアクセス修飾子 - private
プライベートアクセス修飾子は最も厳しいアクセスレベルであり、宣言されたprivateメソッド、変数、コンストラクタは所属クラスからのみアクセスでき、クラスとインターフェースは private として宣言できません。private。
private アクセス型として宣言された変数は、クラス内の public ゲッターメソッドを通じてのみ外部クラスからアクセスできます。
private アクセス修飾子の主な用途は、クラスの実装詳細を隠蔽し、クラスのデータを保護することです。
次のクラスはプライベートアクセス修飾子を使用しています:
例では、Logger クラスの format 変数は private 変数であるため、他のクラスはこの変数の値を直接取得・設定できません。他のクラスがこの変数を操作できるようにするため、2つの public メソッド、getFormat()(format の値を返す)と setFormat(String)(format の値を設定する)を定義しています。
パブリックアクセス修飾子 - public
public として宣言されたクラス、メソッド、コンストラクタ、インターフェースは、他のどのクラスからもアクセスできます。
相互にアクセスする複数の public クラスが異なるパッケージにある場合は、対応する public クラスを含むパッケージをインポートする必要があります。クラスの継承により、クラスのすべての public メソッドと変数はサブクラスに継承されます。
以下のメソッドはパブリックアクセス制御を使用しています:
Java プログラムの main() メソッドは public に設定する必要があります。そうしないと、Java インタプリタはそのクラスを実行できません。
プロテクテッドアクセス修飾子 - protected
protected は以下の2つの観点から分析して説明する必要があります:
サブクラスと基底クラスが同じパッケージにある場合: protected として宣言された変数、メソッド、コンストラクタは、同じパッケージ内の他のどのクラスからもアクセスできます。
サブクラスと基底クラスが同じパッケージにない場合: サブクラス内では、サブクラスのインスタンスは基底クラスから継承した protected メソッドにアクセスできますが、基底クラスのインスタンスの protected メソッドにはアクセスできません。
protected はデータメンバー、コンストラクタ、メソッドメンバーを修飾できます。クラスを修飾することはできません(内部クラスを除く)。。
インターフェースおよびインターフェースのメンバー変数とメンバーメソッドは protected として宣言できません。次の図を見てください:

サブクラスは protected 修飾子で宣言されたメソッドと変数にアクセスできるため、無関係なクラスがこれらのメソッドと変数を使用するのを防ぎます。
以下の親クラスは protected アクセス修飾子を使用しており、サブクラスは親クラスの openSpeaker() メソッドをオーバーライドしています。
openSpeaker() メソッドを private として宣言すると、AudioPlayer 以外のクラスはこのメソッドにアクセスできなくなります。
openSpeaker() を public として宣言すると、すべてのクラスがこのメソッドにアクセスできます。
このメソッドを所属クラスのサブクラスにのみ公開したい場合は、そのメソッドを protected として宣言します。
protected は Java のクラスメンバーアクセス権限修飾子の中で最も理解しにくいものの1つです。詳細については、以下を参照してください:Java protected キーワード詳解。
アクセス制御と継承
以下のメソッド継承のルールに注意してください:
親クラスで public として宣言されたメソッドは、サブクラスでも public でなければなりません。
親クラスで protected として宣言されたメソッドは、サブクラスで protected または public として宣言する必要があり、private として宣言することはできません。
-
親クラスで private として宣言されたメソッドは、サブクラスに継承されません。
非アクセス修飾子
他の機能を実現するために、Java は多くの非アクセス修飾子も提供しています。
static 修飾子は、クラスメソッドとクラス変数を修飾するために使用されます。
final 修飾子は、クラス、メソッド、変数を修飾するために使用されます。final で修飾されたクラスは継承できず、修飾されたメソッドは継承クラスによって再定義できず、修飾された変数は定数であり、変更できません。
abstract 修飾子は、抽象クラスと抽象メソッドを作成するために使用されます。
synchronized と volatile 修飾子は、主にスレッドプログラミングに使用されます。
static 修飾子
-
静的変数:
static キーワードは、オブジェクトから独立した静的変数を宣言するために使用されます。クラスのインスタンスがいくつ生成されても、静的変数のコピーは1つだけです。静的変数はクラス変数とも呼ばれます。ローカル変数は static 変数として宣言できません。
-
静的メソッド:
static キーワードは、オブジェクトから独立した静的メソッドを宣言するために使用されます。静的メソッドはクラスの非静的変数を使用できません。静的メソッドはパラメータリストからデータを取得し、それらのデータを計算します。
クラス変数とメソッドへのアクセスは、直接classname.variablenameとclassname.methodnameの方法でアクセスします。
次の例のように、static 修飾子はクラスメソッドとクラス変数を作成するために使用されます。
上記の例を実行した結果は次のとおりです:
Starting with 0 instances Created 500 instances
final 修飾子
final 変数:
final は「最後の、最終的な」という意味を表し、変数は一度代入されると再代入できません。final で修飾されたインスタンス変数は、明示的に初期値を指定する必要があります。
final 修飾子は通常、static 修飾子と一緒に使用してクラス定数を作成します。
例
final メソッド
親クラスの final メソッドはサブクラスに継承できますが、サブクラスによってオーバーライドすることはできません。
final メソッドを宣言する主な目的は、そのメソッドの内容が変更されるのを防ぐことです。
以下に示すように、final 修飾子を使用してメソッドを宣言します。
final クラス
final クラスは継承できません。final クラスの特性を継承できるクラスはありません。
例
abstract 修飾子
抽象クラス:
抽象クラスはオブジェクトのインスタンス化には使用できません。抽象クラスを宣言する唯一の目的は、将来そのクラスを拡張することです。
クラスは abstract と final の両方で同時に修飾することはできません。クラスが抽象メソッドを含む場合、そのクラスは必ず抽象クラスとして宣言する必要があります。そうしないとコンパイルエラーが発生します。
抽象クラスは抽象メソッドと非抽象メソッドを含むことができます。
例
抽象メソッド
抽象メソッドは実装を持たないメソッドであり、そのメソッドの具体的な実装はサブクラスによって提供されます。
抽象メソッドは final および static として宣言することはできません。
抽象クラスを継承するすべてのサブクラスは、そのサブクラス自体が抽象クラスでない限り、親クラスのすべての抽象メソッドを実装する必要があります。
クラスが複数の抽象メソッドを含む場合、そのクラスは抽象クラスとして宣言する必要があります。抽象クラスは抽象メソッドを含まなくてもかまいません。
抽象メソッドの宣言はセミコロンで終わります。例:public abstract sample();。
例
synchronized 修飾子
synchronized キーワードで宣言されたメソッドは、同時に1つのスレッドからのみアクセスできます。synchronized 修飾子は4つのアクセス修飾子に適用できます。
例
transient 修飾子
シリアル化されたオブジェクトが transient で修飾されたインスタンス変数を含む場合、Java 仮想マシン(JVM)はその特定の変数をスキップします。
この修飾子は変数を定義する文に含まれ、クラスと変数のデータ型を前処理するために使用されます。
例
volatile 修飾子
volatile で修飾されたメンバー変数は、スレッドがアクセスするたびに、共有メモリからそのメンバー変数の値を強制的に再読み取りします。また、メンバー変数が変更されると、スレッドは変更値を共有メモリに強制的に書き戻します。これにより、どの時点でも、2つの異なるスレッドは常に同じメンバー変数の同じ値を参照します。
volatile オブジェクト参照は null の場合があります。
例
通常、あるスレッドが run() メソッドを呼び出し(Runnable で開始されたスレッド)、別のスレッドが stop() メソッドを呼び出します。 もし1行目の中のバッファの active の値が使用される場合、2行目の active の値が false の場合、ループは停止しません。
しかし、上記のコードでは volatile で active を修飾しているため、このループは停止します。
その他の拡張