Java 速習チュートリアル

Java の非アクセス修飾子

1. 非アクセス修飾子について

非アクセス修飾子(Non-access modifiers)は、publicprivate のようにアクセスレベル(可視性)を制御するものではなく、クラス、メソッド、および属性(フィールド)に特別な機能を追加するために使用されます。

最も頻繁に使用される非アクセス修飾子は、finalstatic、そして abstract です。

2. Final 修飾子

既存の属性値を上書き(オーバーライド)されたくない場合は、属性を final として宣言します。

例:

public class Main {
  final int x = 10;
  final double PI = 3.14;

  public static void main(String[] args) {
    Main myObj = new Main();
    myObj.x = 50; // エラーが発生します:final変数に値を代入することはできません
    myObj.PI = 25; // エラーが発生します:final変数に値を代入することはできません
    System.out.println(myObj.x);
  }
}

3. Static 修飾子

static メソッドはクラスそのものに属しており、特定のオブジェクトに属するものではありません。これは、そのクラスのオブジェクトを作成しなくても呼び出せることを意味します。

例:static メソッドを直接呼び出すシンプルな例:

public class Main {
  // Staticメソッド
  static void myStaticMethod() {
    System.out.println("Staticメソッドはオブジェクトを作成せずに呼び出せます");
  }

  // Mainメソッド
  public static void main(String[] args) {
    myStaticMethod();         // 直接呼び出し
    Main.myStaticMethod();    // またはクラス名を使用して呼び出し
  }
}

注記: static メソッドはクラス自体に属します。オブジェクトを作成せずに呼び出すことができますが、その内部でオブジェクトに属する変数(インスタンス変数)やメソッドを使用することはできません。

4. Abstract 修飾子

abstract メソッドは abstract クラス内にのみ存在し、メソッドの本体(シグネチャのみで実装がない状態)を持ちません。メソッドの本体は、そのクラスを継承したサブクラスによって提供されます。

Main.java

// 抽象クラス (abstract class)
abstract class Main {
  public String fname = "John";
  public int age = 24;
  public abstract void study(); // 抽象メソッド (abstract method)
}

Second.java

// サブクラス (Mainを継承)
class Student extends Main {
  public int graduationYear = 2018;
  public void study() { // 抽象メソッドの本体はここで実装されます
    System.out.println("一日中勉強しています");
  }
}

5. 非アクセス修飾子一覧

クラス(Classes)に対しては、final または abstract を使用できます。

モディファイア説明
final他のクラスがこのクラスを継承することはできません(詳細は「継承(Inheritance)」の章で解説)。
abstractこのクラスを使用してオブジェクトを作成することはできません。抽象クラスにアクセスするには、別のクラスから継承する必要があります(詳細は「継承」および「抽象化(Abstraction)」の章で解説)。

属性(フィールド)およびメソッドに対しては、以下のいずれかを使用できます。

モディファイア説明
final属性やメソッドを上書き、または変更することができなくなります。
static属性やメソッドがオブジェクトではなくクラスに属するようになります。これにより、すべてのオブジェクトで同じ static 属性を共有し、オブジェクトを作成せずに static メソッドを呼び出せます。
abstract抽象クラス内でのみ使用可能で、メソッドに対してのみ適用できます。メソッドは本体を持ちません(例:abstract void run();)。本体は継承したサブクラス側で提供されます。
transientその属性を含むオブジェクトをシリアライズ(直列化)する際に、その属性やメソッドはスキップされます。
synchronizedメソッドに対して一度に1つのスレッドしかアクセスできないように制御します。
volatile属性の値がスレッドローカルにキャッシュされず、常に「メインメモリ」から読み込まれるようにします。