解決策 1: オブジェクト登録システム
提示された 2 つのスニペットは、基本的に、作成したばかりの匿名クラス インスタンスへの参照を格納するか、そのカスタム フィールドにすぐにアクセスするかの選択を行いました。一方を行うと、他方を行う能力が失われるように思われます。
妥協を実現する 1 つの方法は、オブジェクト登録システムを用意し、匿名クラスでインスタンス初期化子( JLS 8.6 ) を使用してこのシステムに自己登録することです。
Object[]
以下は、単純な登録システムを使用した単純な概念実証です。
final Object[] registrar = { null };
int k = new HashSet<Integer>(){
{ registrar[0] = this; }
int i= 666;
}.i;
Set<Integer> set = (Set<Integer>) registrar[0];
System.out.println(k); // 666
System.out.println(set.getClass().isAnonymousClass()); // true
基本的に 1-element を使用し、匿名クラスのインスタンス初期化子で、この配列Object[]
に「登録」します。this
これは単なる概念実証であることに注意してください。本番コードでは、これよりも堅牢で型安全なオブジェクト登録システムを使用します。
解決策 2: タプル
このアプローチは、匿名クラスに複数の「フィールド」がある場合にうまく機能します。それらをすべてtupleにパックするだけthis
で、匿名クラスにへの参照が含まれていることを確認してください。
Object[]
タプルを使用した簡単な概念実証は次のとおりです。
Object[] tuple = new HashSet<Integer>(){
Object[] tuple = { this, 666, 13, "XXX", "OMG ABUZE" };
}.tuple;
Set<Integer> set = (Set<Integer>) tuple[0];
set.add(null);
System.out.println(set.getClass().isAnonymousClass()); // true
System.out.println(Arrays.toString(tuple));
// [[null], 666, 13, XXX, OMG ABUZE]
本番コードでCustomTuple
は、よりオブジェクト指向でタイプセーフなクラスを使用します。これは、「メソッドが 2 つの値を返すにはどうすればよいか」という問題に対する類似の解決策であることに注意してください。これらの情報をすべて取得する 1 つの値を返すだけです。