Java コンストラクタ/デストラクタとガベージ・コレクションの関係

Javaのコンストラクタとデストラクタ(的なもの)の紹介をします。

デストラクタを理解するにあたり、Javaのガベージ・コレクションの仕組みの理解が必要なため合わせて説明します。

さて、デストラクタに「的なもの」と記載しました。なぜ「的なもの」が付くかと言うと、Javaにはデストラクタは無いからです。Javaの思想として無いので、これからも追加実装されることは無いでしょう。デストラクタ「的なもの」と記載したのはfinalizeメソッドのことです。

それでは、それぞれの詳細をご紹介していきます。

コンストラクタ

インスタンス生成時に呼ばれる関数です。クラス名と同じ名前にします。引数の数は任意です。インスタンスの初期化処理を行うための処理です。

例えばTestというクラスを作ったとします。

// クラスを定義
class Test {
}

このクラスを使用するためにインスタンス化します。

// インスタンス化
Test test = new Test();

Testクラスをインスタンス化した際に、Testクラスのコンストラクタが自動で呼び出されます。上記のようにコンストラクタを書かなかった場合には、自動で生成されるデフォルトコンストラクタが呼び出されます。

デフォルトコンストラクタは何もせず、あえて記載するとこんな感じです。

// クラスを定義
class Test {
  // デフォルトコンストラクタ
  Test(){
  }
}

業務で使用するようなソースコードでは、デフォルトコンストラクタはあまり使用しません。なぜなら初期処理をしたいことが多いからです。

例えば上記のTestクラスについて考えてみると、いつのテストなのか、何のテストなのか、平均点、取得した点数などインスタンス作成時点で設定しておきたい初期処理が考えられます。

ソースコードで表すとこのようになります。まずはクラス定義側のソースコードです。

// クラスを定義
class Test {

  LocalDateTime time;
  String name;
  int averageScore;
  int score;

  // コンストラクタ
  Test(LocalDateTime time, String name, int averageScore, int score){
    this.time = time;
    this.name = name;
    this.averageScore = averageScore;
    this.score = score;
  }
}

続いて定義したクラスを使用する側のソースコードです。

// インスタンス化
Test test = new Test(time, name, averageScore, score);

コンストラクタはこのように定義し、使用します。

デストラクタ

デストラクタはインスタンスが解放される前に呼び出される処理ですが、Javaにはありません。Javaの思想に基づいたもので、インスタンスが解放されるのは自動で行われます。

これに対して、デストラクタの無い言語は「オブジェクト指向を名乗るな」など一部で過激な発言が飛び出しています。

デストラクタ的なものとしてfinalize()があげられることがありますが、ガベージ・コレクションと関連があり、使用するのに注意が必要です。finalize()はインスタンスが解放されるタイミングで実施されるのではなく、ガベージ・コレクションが実施されるタイミングで実施されます。

Oracle JDK9 API仕様 finalize

分かりやすい記事
http://lab.astamuse.co.jp/entry/2018/07/25/114500

ガベージ・コレクション

ガベージ・コレクションは使用しなくなったオブジェクトを一定の条件で消去します。しかしガベージ・コレクションでの(インスタンス含む)オブジェクト消去前に、finalize()が呼ばれるとは限りません。

詳細はこの記事がわかりやすいです。