Java : Reference (参照) - API使用例
Reference (Java SE 18 & JDK 18) の使用例まとめです。
だいたいのメソッドを網羅済みです。
API仕様のおともにどうぞ。
概要
Referenceは、(弱)参照オブジェクトのベースとなるクラスです。
Java 18 の時点では、
- ソフト参照 (SoftReference)
- 弱参照 (WeakReference)
- ファントム参照 (PhantomReference)
が提供されています。
一番よく使われるのは、WeakReference でしょうか。
とはいえ、あまり Reference に頼る設計にはしないほうがよいと、個人的には思います。
(GC に依存した挙動となり、テストもしづらいため)
// 弱参照(WeakReference)の使用例です。
var sb = new StringBuilder("abcd");
final Reference<StringBuilder> ref = new WeakReference<>(sb);
System.out.println(ref.get()); // abcd
// 変数 sb による強参照が残っている状態です。
System.gc();
System.out.println(ref.get()); // abcd
// 変数 sb の強参照をクリアします。
sb = null;
System.out.println(ref.get()); // abcd
// その状態で、GCを要求します。
System.gc();
System.out.println(ref.get()); // null
補足
- 本記事のコード例では、GCを実行するために System.gc メソッドを使っています。
- しかし、一般的なJavaプログラムでは、System.gc を直接呼び出すことはあまりおすすめしません。
Javaシステムが自分自身の最適なタイミングでGCを実行してくれるためです。
メソッド
void clear ()
final var sb = new StringBuilder("abcd");
final Reference<StringBuilder> ref = new WeakReference<>(sb);
System.out.println(ref.get()); // abcd
ref.clear();
System.out.println(ref.get()); // null
final var sb = new StringBuilder("abcd");
final var queue = new ReferenceQueue<StringBuilder>();
final Reference<StringBuilder> ref = new WeakReference<>(sb, queue);
System.out.println(ref.get()); // abcd
ref.clear();
System.out.println(ref.get()); // null
// キューには入りません。
System.out.println(queue.poll()); // null
protected Object clone ()
常に CloneNotSupportedException が発生します。
よって、Reference を clone するべきではありません。
final var sb = new StringBuilder("abcd");
final var ref = new WeakReference<StringBuilder>(sb) {
public void test() {
try {
clone();
} catch (CloneNotSupportedException e) {
System.out.println("CloneNotSupportedException!");
}
}
};
ref.test();
// 結果
// ↓
//CloneNotSupportedException!
boolean enqueue ()
final var sb = new StringBuilder("abcd");
final var queue = new ReferenceQueue<StringBuilder>();
final Reference<StringBuilder> ref = new WeakReference<>(sb, queue);
System.out.println(ref.get()); // abcd
final var ret = ref.enqueue();
System.out.println(ret); // true
System.out.println(ref.get()); // null
System.out.println(queue.poll()); // java.lang.ref.WeakReference@7625b376
final var sb = new StringBuilder("abcd");
final Reference<StringBuilder> ref = new WeakReference<>(sb);
System.out.println(ref.get()); // abcd
final var ret = ref.enqueue();
System.out.println(ret); // false
System.out.println(ref.get()); // null
T get ()
var sb = new StringBuilder("abcd");
final Reference<StringBuilder> ref = new WeakReference<>(sb);
System.out.println(ref.get()); // abcd
sb = null;
System.out.println(ref.get()); // abcd
System.gc();
System.out.println(ref.get()); // null
boolean isEnqueued ()
非推奨です。
static void reachabilityFence (Object ref)
まだ動作を確認しきれていないため、コード例も準備できていません。
(いずれ更新するかもしれません…)
final boolean refersTo (T obj)
var sb1 = new StringBuilder("abcd");
final Reference<StringBuilder> ref = new WeakReference<>(sb1);
System.out.println(ref.refersTo(sb1)); // true
var sb2 = new StringBuilder("XYZ");
System.out.println(ref.refersTo(sb2)); // false
関連記事
- API 使用例