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 つの異なるアクセス権をサポートしています。
デフォルト (デフォルトとも呼ばれます) は、同じパッケージ内で表示され、修飾子を使用しません。
プライベート。private 修飾子で指定され、同じクラス内で表示されます。
public、public 修飾子で指定され、すべてのクラスに表示されます。
Protected、protected 修飾子で指定され、同じパッケージ内のクラスおよびすべてのサブクラスに表示されます。
デフォルトのアクセス修飾子を使用して宣言された変数とメソッドは、同じパッケージ内のクラスから参照できます。インターフェイス内の変数は暗黙的にpublic static final
として宣言され、インターフェイス内のメソッドにはデフォルトでpublic
のアクセス許可が与えられます。
例:
次の例に示すように、変数とメソッドは修飾子なしで宣言できます。
String version = "1.5.1"; boolean processOrder() { return true; }
private アクセス修飾子は最も制限の厳しいアクセス レベルであるため、プライベートとして宣言されたメソッド、変数、コンストラクターには、それらが属するクラスからのみアクセスでき、クラスとインターフェイスはプライベートとして宣言できません。
プライベート アクセス型として宣言された変数には、クラス内のパブリック getter メソッドを介して外部クラスからのみアクセスできます。
Private アクセス修飾子の使用は、主にクラスの実装の詳細を隠し、クラスのデータを保護するために使用されます。
次のクラスはプライベート アクセス修飾子を使用します。
public class Logger { private String format; public String getFormat() { return this.format; } public void setFormat(String format) { this.format = format; } }
この例では、Logger クラスのフォーマット変数はプライベート変数であるため、他のクラスは変数の値を直接取得および設定できません。他のクラスがこの変数を操作できるようにするために、 getFormat()
(format の値を返す) とsetFormat(String)
(format の値を設定する) という 2 つのpublic
メソッドが定義されています。
public として宣言されたクラス、メソッド、コンストラクター、およびインターフェイスには、他のクラスからアクセスできます。
相互にアクセスする複数のパブリック クラスが異なるパッケージで配布されている場合は、対応するパブリック クラスが配置されているパッケージをインポートする必要があります。クラスの継承により、クラスのすべてのパブリック メソッドと変数はそのサブクラスに継承できます。
次の機能はパブリック アクセス制御を使用します。
public static void main(String[] arguments) { // ... }
Java プログラムの main() メソッドは public に設定する必要があります。そうしないと、Java インタプリタはクラスを実行できません。
protected として宣言された変数、メソッド、およびコンストラクターには、同じパッケージ内の他のクラス、または異なるパッケージ内のサブクラスからアクセスできます。
保護されたアクセス修飾子はクラスとインターフェイスを変更できません。メソッドとメンバー変数は保護されると宣言できますが、インターフェイスのメンバー変数とメンバー メソッドは保護されると宣言できません。
サブクラスは、Protected 修飾子を使用して宣言されたメソッドと変数にアクセスできるため、無関係なクラスがこれらのメソッドや変数を使用しないように保護されます。
次の親クラスは protected アクセス修飾子を使用し、サブクラスは親クラスの openSpeaker() メソッドをオーバーライドします。
class AudioPlayer { protected boolean openSpeaker(Speaker sp) { // 实现细节} } class StreamingAudioPlayer extends AudioPlayer { boolean openSpeaker(Speaker sp) { // 实现细节} }
openSpeaker() メソッドがプライベートと宣言されている場合、AudioPlayer 以外のクラスはこのメソッドにアクセスできません。
openSpeaker() が public として宣言されている場合、すべてのクラスがこのメソッドにアクセスできます。
メソッドをそのクラスのサブクラスにのみ表示したい場合は、メソッドを保護済みとして宣言します。
メソッド継承に関する次のルールに注意してください。
親クラスで public として宣言されたメソッドは、子クラスでも public である必要があります。
親クラスで protected として宣言されたメソッドは、サブクラスで protected または public として宣言されます。非公開と宣言することはできません。
親クラスでプライベートとして宣言されたメソッドは継承できません。
他のいくつかの関数を実装するために、Java は多くの非アクセス修飾子も提供します。
静的修飾子。クラスメソッドとクラス変数の作成に使用されます。
Final 修飾子は、クラス、メソッド、および変数を変更するために使用されます。final によって変更されたクラスは継承できません。変更されたメソッドは継承されたクラスによって再定義できません。また、変更された変数は定数であるため変更できません。
抽象修飾子。抽象クラスと抽象メソッドの作成に使用されます。
synchronized 修飾子と volatile 修飾子は、主にスレッド プログラミングに使用されます。
静的変数:
static キーワードは、オブジェクトから独立した静的変数を宣言するために使用されます。クラスがインスタンス化するオブジェクトの数に関係なく、静的変数のコピーは 1 つだけ存在します。静的変数はクラス変数とも呼ばれます。ローカル変数は静的変数として宣言できません。
静的メソッド:
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("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
最終的な変数:
最終変数は明示的に 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 修飾子を使用してメソッドを宣言します。
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 および static として宣言できません。
抽象クラスを継承するサブクラスは、そのサブクラスが抽象クラスである場合を除き、親クラスのすべての抽象メソッドを実装する必要があります。
クラスに複数の抽象メソッドが含まれる場合、そのクラスは抽象として宣言される必要があります。抽象クラスには抽象メソッドを含める必要はありません。
抽象メソッドの宣言はセミコロンで終わります。例: public abstract sample();
例:
public abstract class SuperClass{ abstract void m(); //抽象方法} class SubClass extends SuperClass{ //实现抽象方法void m(){ ......... } }
synchronized キーワードを使用して宣言されたメソッドには、同時に 1 つのスレッドのみがアクセスできます。 Synchronized 修飾子は 4 つのアクセス修飾子に適用できます。
例:
public synchronized void showDetails(){ ....... }
シリアル化されたオブジェクトに、一時的に変更されるインスタンス変数が含まれている場合、Java 仮想マシン (JVM) はその特定の変数をスキップします。
この修飾子は変数を定義するステートメントに含まれており、クラスと変数のデータ型を前処理するために使用されます。
例:
public transient int limit = 55; // will not persist public int b; // will persist
volatile で変更されたメンバー変数がスレッドによってアクセスされるたびに、メンバー変数の値が共有メモリから強制的に再読み取りされます。さらに、メンバー変数が変更されると、スレッドは変更された値を共有メモリに書き戻すことを強制されます。このようにして、いつでも 2 つの異なるスレッドがメンバー変数の同じ値を参照します。
揮発性オブジェクト参照は null になる可能性があります。
例:
public class MyRunnable implements Runnable { private volatile boolean active; public void run() { active = true; while (active) // line 1 { // 代码} } public void stop() { active = false; // line 2 } }
一般に、run() メソッドは 1 つのスレッドで呼び出され、stop() メソッドは別のスレッドで呼び出されます。バッファ内の line 1 の active の値が使用されている場合、line 2 の active が false に設定されていてもループは停止しません。