2012-04-20 7 views
1

私は任意のオブジェクトグラフを保存するはずの保存/読み込みフレームワークを持っています。これには、非静的ネストされたクラスのインスタンスが含まれます。どのようにして、Androidでのリフレクションを通じてメンバークラスをインスタンス化できますか?

ネストされたクラスは、それらを作成した親クラスのインスタンスによって所有され、ネストされたクラスは、そのインスタンスが合成フィールドを使用してどのインスタンスに属するかを認識します。簡単な例として

、私はこのクラスを提示:「標準」のコンパイラで

public class Foo implements Savable { 
    private class Bar implements Savable { 
    public void saveState(Saver saver) { 
     saver.putInt(3); 
    } 
    } 
    private Bar myBar = new Bar(); 
    public void saveState(Saver saver) { 
    saver.putSavable(myBar); 
    } 
} 

、次のコードは、オブジェクト(myBar)で取ることだけで正常に動作し、その親を見つける(特定のインスタンス

if (objectClass.isMemberClass()) { 
    //We are a member class, which means we are a non-static inner class, and therefore must save our parent. 
    Field[] fields = objectClass.getDeclaredFields(); 
    //We loop through each of our fields to find the synthetic field created by the compiler that points to our parent. 
    for (Field f : fields) { 
    String name = f.getName(); 
    //The synthetic field pointing to the parent is named something like "this$0". At least, with the "standard" compiler it is. 
    if (name.startsWith("this$")) { 
     f.setAccessible(true); 
     Savable parent = (Savable)f.get(objectClass); 
     saver.putSavable("_parent", parent); 
     break; 
    } 
    } 
    if (!saver.containsKey("_parent")) { 
    throw new RuntimeException("Could not find the owner of inner class: " + objectClass); 
    } 
} 

をので、私はこれは単に「標準」のコンパイラにでは正常に動作し、言ったように:Foo)、そして子供とそれの参照を保持します。その後、ロード時に、親クラスのインスタンスを取り込んでインスタンス化し、親を渡すコンストラクタを探すことを除いて、同様のことが起こります。

しかし!

Android VMでは動作しません。合成フィールドはありません。コンストラクタは、親インスタンスを取らないように、すべて正常に見えます。

ここにはSOLがありますか?このVMは私のアプローチが明らかに好きではありません。内部クラスが親クラスインスタンスへの参照を保存する必要があることを知ることなく、ここで何ができるのですか?

+0

ooi whats SOL mean? – Blundell

+0

これは "$#!%Out of Luck" –

答えて

0

さて、私は間違った木を吠えていました。私が概説した方法は、Androidだけでなく他の場所でもうまく機能します。問題は、この場合インスタンス化しようとしていたクラスがstatic内部クラスであることでした。したがって、それはメンバクラスでしたが、その外部クラスへの参照を持っていませんでした。私は合成コンストラクタ/フィールドを探す前にif (!Modifier.isStatic(objectClass.getModifiers()))をチェックするだけです。

関連する問題