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(つまり、デフォルトであり、何も書き込まない):修飾子なしで同じパッケージに表示されます。使用するオブジェクト:クラス、インターフェース、変数、メソッドです。
- 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 |
デフォルトアクセス修飾子-キーワードは一切使用されません
デフォルトアクセス修飾子によって宣言された変数とメソッドは、同じパッケージ内のクラスに表示されます。 インターフェイスの変数は暗黙的にpublic static finalとして宣言され、デフォルトでインターフェイスのメソッドのアクセス権はpublic
です。
次の例に示すように、変数とメソッドの宣言は、修飾子なしで宣言できます。
実例
String version = "1.5.1";
boolean processOrder() {
return true;
}
プライベートアクセス修飾子-private
プライベートアクセス修飾子は最も厳密なアクセスレベルであるため、privateとして宣言されたメソッド、変数、およびコンストラクタは、それらが属するクラスによってのみアクセスでき、クラスとインターフェイスをprivateとして宣言できません。
プライベートアクセス型として宣言された変数は、クラス内にあるパブリックgetterメソッドによって外部クラスからのみアクセスできます。
Privateアクセス修飾子の使用は、主にクラスの実装の詳細を非表示にし、クラスのデータを保護するために使用されます。
下記のクラスにはプライベートアクセス修飾子が使用されます。
public class Logger {
private String format;
public String getFormat() {
return this.format;
}
public void setFormat(String format) {
this.format = format;
}
}
この例では、Loggerクラスのformat変数はプライベート変数であるため、他のクラスがこの変数の値を直接取得および設定できません。 他のクラスが変数を操作できるようにするために、2つのpublicメソッドが定義されています。getFormat() (formatの値を返します)とsetFormat(String)(format値を設定します)
パブリックアクセス修飾子-public
publicとして宣言されたクラス、メソッド、コンストラクタ、およびインターフェースには、他のクラスからアクセスできます。
お互にアクセスする複数のpublicクラスが異なるパッケージで配布されている場合は、対応するpublicクラスが配置されているパッケージをインポートする必要があります。クラスの継承により、クラスのすべてのパブリックメソッドと変数はそのサブクラスによって継承できます。
次の関数は、パブリックアクセス制御を使用します。
public static void main(String[] arguments) {
// ...
}
Javaプログラムのmain()メソッドはpublicに設定する必要があります。そうしないと、Javaインタープリタはクラスを実行できません。
保護されたアクセス修飾子-protected
protectedについては、次の2つのポイントから分析および説明する必要があります。
- サブクラスと基本クラスは同じパッケージに含まれています。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と宣言されているメソッドは、サブクラスでprotecteと宣言されているか、publicとして宣言されており、privateとして宣言できません。
- 親クラスでprivateとして宣言されたメソッドは継承できません。
非アクセス修飾子
他のいくつかの機能を実現するために、Javaは多くの非アクセス修飾子も提供します。
static修飾子は、クラスメソッドとクラス変数を変更するために使用されます。
final修飾子は、クラス、メソッド、および変数を変更するために使用されます。finalに変更されたクラスは継承できません。変更されたメソッドは、継承クラスによって再定義できません。変更された変数は定数であり、変更できません。
abstract修飾子は、抽象クラスと抽象メソッドを作成するために使用されます。
synchronizedとvolatile修飾子は、主にマルチスレッドの処理に使用されます。
static修飾子
静的変数:
staticキーワードは、オブジェクトから独立した静的変数を宣言するために使用されます。クラスがインスタンス化するオブジェクトの数に関係なく、静的変数のコピーは1つだけです。 静的変数はクラス変数とも呼ばれます。 ローカル変数をstatic変数として宣言できません。
静的メソッド:
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("Starting with " +
InstanceCounter.getCount() + " instances");
for (int i = 0; i < 500; ++i){
new InstanceCounter();
}
System.out.println("Created " +
InstanceCounter.getCount() + " instances");
}
}
上記の実例が実行した結果は次のとおりです。
Starting with 0 instances
Created 500 instances
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キーワードで宣言されたメソッドには、一回に1つのスレッドでのみアクセスできます。 synchronized修飾子は、4つのアクセス修飾子に適用できます。
実例
public synchronized void showDetails(){
.......
}
transient修飾子
シリアル化されたオブジェクトはtransientに変更されたインスタンス変数が含まれている場合、Java仮想マシン(JVM)は特定の変数をスキップします。
この修飾子は、変数を定義するステートメントに含まれ、クラスと変数のデータ型を前処理するために使用されます。
実例
public transient int limit = 55; // 永続化しない
public int b; // 永続化する
volatile修飾子
volatileに変更されたメンバー変数がスレッドによってアクセスされる場合、共有メモリから強制的にメンバー変数の値を再読み取ります。さらに、メンバー変数が変更されると、スレッドは変更された値を強制的に共有メモリに書き戻ります。このように、いつでも、2つの異なるスレッドは常にメンバー変数の同じ値を参照します。
volatileオブジェクトの参照が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()メソッドは別のスレッドで呼び出されます。最初の行のバッファのactive値が使用されている場合、二行目のactive値がfalseでもループは停止しません。
ただし、上記のコードでは、volatileを使用してactiveを変更しているため、ループは停止します。
コメントを残す