HOWTO · Java

Java でオブジェクトを削除する

Java のオブジェクトを削除する方法を 2つの例で紹介しています。

Java でオブジェクトを削除する方法と、ガベージコレクタを利用する方法を以下の例で学びます。

Java Objectnull を参照して削除する

Java オブジェクトを削除する最初の例では、変数 nameage を初期化するコンストラクタを持つクラスを作成します。main メソッドでは、User クラスの object を作成し、nameage の値を渡します。オブジェクトが初期化されたので、これを使って age を取得し、それを比較してメッセージを表示することができます。しかし、その後は myObject を削除してそれ以上使えないようにしたい。

そのためには、もう一度 myObject を null で初期化します。一度 myObjectnull になってしまうと、それを使ってそのメソッドや変数を呼び出すことはできず、例外が発生します。System.gc() は、メモリを解放するために空のフィールドやオブジェクトが残らないように、残ったゴミを回収するために使われます。

User クラスに finalize() メソッドがあることがわかります。これは、ガベージを収集する前にオブジェクト上で呼び出されます。

public class JavaDeleteObject {
  public static void main(String[] args) {
    User myObject = new User("John", 30);
    int userAge = myObject.age;

    if (userAge > 25) {
      System.out.println("User age is : " + userAge);
    } else {
      System.out.println("User age is less than 25 : " + userAge);
    }
    myObject = null;
    System.gc();

    System.out.println(myObject.age);
  }
}

class User {
  String name;
  int age;

  User(String n, int a) {
    name = n;
    age = a;
  }

  protected void finalize() {
    System.out.println("Object is garbage collected.");
  }
}

出力:

User age is : 30
Object is garbage collected.
Exception in thread "main" java.lang.NullPointerException
	at com.company.JavaDeleteObject.main(JavaDeleteObject.java:18)

Java はスコープに閉じ込められたオブジェクトを null を参照して削除する

以下のコードでは、3つのデータメンバを持つ Student クラスがあり、これらのメンバにはクラスのパラメータ化されたコンストラクタを用いて値が代入されます。このクラスには showDetails() メソッドと showNextIndex() メソッドがあります。また、次の学生のインデックスを表示する finalize() メソッドもあります。

新しいオブジェクトは Student クラスの new キーワードを用いて作成されます。Student クラスのメソッドは student1student2 オブジェクトに対して呼び出されます。コードの後半では、スコープ内にさらに多くの Student クラスオブジェクトを作成しています。これらを使用した後、System.gc() を呼び出し、このスコープ内に作成した 2つのオブジェクトをガベージコレクションするように JVM に要求します。

スコープに入る前に nextIndex の値を 3 にインクリメントし、スコープを抜ける前には 5 にします。値 nextIndex をデクリメントするには、オブジェクトがガベージコレクションされる前に System.runFinalization() を使って finalize() メソッドを 2 回呼び出し、値 5 を指定します。

その後、スコープ内にあった値を除いた正しい nextIndex 値が表示されます。

class Student {
  private int index;
  private String name;
  private int age;
  private static int nextIndex = 1;

  Student(String name, int age) {
    this.name = name;
    this.age = age;
    this.index = nextIndex++;
  }

  public void showDetails() {
    System.out.println("Student at Index : " + index + ", Student name: " + name + ", age: " + age);
  }

  public void showNextIndex() {
    System.out.println("Next Index: " + nextIndex);
  }

  protected void finalize() {
    --nextIndex;
  }
}

class UseStudent {
  public static void main(String[] args) {
    Student student1 = new Student("John", 23);
    Student student2 = new Student("Doe", 20);
    student1.showDetails();
    student2.showDetails();
    student1.showNextIndex();
    student2.showNextIndex();
    {
      Student student3 = new Student("Sam", 22);
      Student student4 = new Student("Ben", 21);
      student3.showDetails();
      student4.showDetails();
      student3.showNextIndex();
      student4.showNextIndex();

      student3 = student4 = null;
      System.gc();
      System.runFinalization();
    }
    student2.showNextIndex();
  }
}

出力:

Student at Index : 1, Student name: John, age: 23
Student at Index : 2, Student name: Doe, age: 20
Next Index: 3
Next Index: 3
Student at Index : 3, Student name: Sam, age: 22
Student at Index : 4, Student name: Ben, age: 21
Next Index: 5
Next Index: 5
Next Index: 3