クラス、インタフェース、メソッド、コンストラクタ、変数には、下記の 修飾子 を指定することができます。
| 修飾子 | クラス | インタ フェース | メソッド | コンスト ラクタ | ブロック | 変数 | 説明 |
|---|---|---|---|---|---|---|---|
| public | ○ | ○ | ○ | ○ | × | ○ | アクセス修飾子 |
| protected | ○ | ○ | ○ | ○ | × | ○ | アクセス修飾子 |
| private | ○ | ○ | ○ | ○ | × | ○ | アクセス修飾子 |
| static | ○ | ○ | ○ | × | × | ○ | スタティック修飾子 |
| final | ○ | × | ○ | × | × | ○ | ファイナル修飾子 |
| abstract | ○ | ○ | ○ | × | × | × | 抽象修飾子 |
| native | × | × | ○ | × | × | × | ネイティブ修飾子 |
| synchronized | × | × | ○ | × | ○ | × | 同期修飾子 |
| transient | × | × | × | × | × | ○ | 一時的修飾子 |
| volatile | × | × | × | × | × | ○ | 揮発性修飾子 |
| strictfp | ○ | ○ | ○ | × | × | × | 厳密浮動小数修飾子 |
| const | × | × | × | × | × | × | 定数 |
public、protected、private は アクセス修飾子 と呼ばれ、指定した変数やクラスなどを、どの範囲から参照可能かのスコープを制御するのに用いられます。クラス、インタフェース、メソッド、コンストラクタ、変数の修飾子として利用できます。
| アクセス修飾子 | 自ファイル | 他ファイル | |||
|---|---|---|---|---|---|
| 自クラス | サブクラス | 他クラス | サブクラス | 他クラス | |
| public | ○ | ○ | ○ | ○ | ○ |
| protected | ○ | ○ | ○ | ○ | × |
| なし | ○ | ○ | ○ | × | × |
| private | ○ | × | × | × | × |
public は「すべてのクラスからの参照を許す」、protected は「他ファイル・他クラスからのアクセスをプロテクトする」、private は「自クラスからのアクセスしか許さない」という意味になります。
public class AccessTest1 {
// public, protected, 無し, privateな値の定義
public int publicValue;
protected int protectedValue;
/* 無し */ int normalValue;
private int privateValue;
public static void main(String[] args) {
}
// 自ファイル・自クラスからのアクセステスト
public AccessTest1() {
this.publicValue = 1;
this.protectedValue = 2;
this.normalValue = 3;
this.privateValue = 4;
}
}
class AccessTest2 extends AccessTest1 {
// 自ファイル・サブクラスからのアクセステスト
void AccessTest2() {
this.publicValue = 1;
this.protectedValue = 2;
this.normalValue = 3;
// this.privateValue = 4; ← アクセスできない
}
}
class AccessTest3 {
// 自ファイル・他クラスからのアクセステスト
void AccessTest3() {
AccessTest1 o = new AccessTest1();
o.publicValue = 1;
o.protectedValue = 2;
o.normalValue = 3;
// o.privateValue = 4; ← アクセスできない
}
}
public class AccessTest4 extends AccessTest1 {
public static void main(String[] args) {
}
// 他ファイル・サブクラスからのアクセステスト
AccessTest4() {
this.publicValue = 1;
this.protectedValue = 2;
// this.normalValue = 3; ← アクセスできない
// this.privateValue = 4; ← アクセスできない
}
}
class AccessTest5 {
// 他ファイル・他クラスからのアクセステスト
AccessTest5() {
AccessTest1 o = new AccessTest1();
o.publicValue = 1;
// o.protectedValue = 2; ← アクセスできない
// o.normalValue = 3; ← アクセスできない
// o.privateValue = 4; ← アクセスできない
}
}
static は、クラスがインスタンス化されていなくても、そのクラス、メソッド、変数などを参照可能であることを示します。
class クラス名 {
public static void main(String[] args) {
:
}
public static final double PI = 3.14159265358979323846;
public static double sin(double a) {
:
}
public static class クラスB {
:
}
}
例えば、java.lang.Math クラスの sin() メソッドは static 宣言されているので、java.lang.Math.sin() として呼び出すことができますが、もし、static 宣言されていなければ、下記のように呼び出す必要があります。
// static 宣言されていれば x = java.lang.Math.sin(y); // 直接呼び出せる // static 宣言されていなければ java.lang.Math m = new java.lang.Math(); // インスタンス化が必要 x = m.sin(y);
final は上書きされないことを意味します。クラスに用いた場合はサブクラスを定義できないことを、メソッドに用いた場合はサブクラスでメソッドをオーバーロードできないことを、変数に用いた場合は誰もその変数を変更できないことを意味します。
final class クラス名 {
:
}
class クラス名 {
final 型 メソッド名(引数) {
:
}
public static final double PI = 3.14159265358979323846;
}
abstract は、クラス、インタフェース、メソッドが抽象的なものであり、不完全なものであることを示します。メソッド名、引数の型などのみを定義し、サブクラスが必ず実装しなくてはならない機能を明確にしておくのが主な利用目的です。
抽象クラス はそのままではインスタンス化することができず、必ずサブクラスを定義して不完全なメソッドの実体を定義してから使用する必要があります。抽象クラスは通常、ひとつ以上の 抽象メソッド を含みます。抽象メソッドはメソッド名、引数の型のみが定義されていますので、どこかでその中身を定義する必要があります。
abstract class クラス名 {
:
abstract void testFunction(int a);
:
}
インタフェースは常に抽象です。以前は下記のように abstract interface と記述していましたが、最近では書かないことが推奨されています。
abstract interface クラス名 {
:
abstract void testFunction(int a);
:
}
抽象クラスとインタフェースは用途は似ていますが、抽象クラスは抽象メソッド以外の通常のメソッドも記述できる代わりに、ひとつのクラスが複数の抽象クラスを継承することができません。
native は、メソッドが ネイティブメソッド であることを示します。ネイテブメソッドは型、メソッド名、引数の型といった作法のみを定義するもので、C言語など他の言語を用いてその中身を実装する必要があります。ネイティブメソッドの詳しい作成方法の説明は省略します。
class クラス名 {
:
public native void testFunction(int a);
:
}
synchronized 修飾子付きのメソッドがマルチスレッド環境で実行される場合、メソッドのインスタンスを対象として排他制御が行われます。ひとつのインスタンスが複数のスレッドを持つ場合は排他制御が行われますが、スレッドが複数のインスタンスで実行される場合の排他制御は行われませんので注意してください。詳細は「スレッド」の章を参照してください。
class クラス名 {
synchronized void メソッド() {
:
}
}
上記は、下記のコードと同等の意味を持ちます。
class クラス名 {
void メソッド() {
synchronized (this) {
:
}
}
}
ディスクに保存したりネットワークで送信するために、オブジェクトの情報をバイトストリームに自動変換することをシリアライズといいますが、transient 修飾子付きの変数は一時的な変数であり、シリアライズの対象から除外されます。
class クラス名 {
transient String tmp;
}
マルチスレッドの場合、それぞれのスレッドは性能向上のために変数のコピーを参照・変更し、その値を元の場所(メモリ)に書き戻さないことがあります。つまり、同じ変数でもスレッドによって値が異なるという現象が発生します。複数のスレッドから参照される可能性のある変数に volatile をつけることにより、この問題を回避することができます。
class クラス名 {
volatile int nCount;
}
strictfp を指定したクラスでは、float や double の浮動小数点演算がプラットフォームに依存しない、厳密な動作をすることになります。strictfp を指定しない場合の浮動小数点演算は、プラットフォームに依存し、高速だけれどもプラットフォームによって若干結果が異なります。
strictfp class クラスA {
double x, y;
:
}
const は、C/C++ 言語などで値を変更することができない変数を示しますが、現在の Java ではキーワードのみが定義されており、実際に使用されるケースはありません。