1

任意のオブジェクト グラフを保存することになっている保存/読み込みフレームワークがあります。これには、静的ではないネストされたクラスのインスタンスが含まれます。

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

簡単な例として、次のクラスを紹介します。

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) を取り込み、その親 ( の特定のインスタンス) を見つけてFoo、子との参照を保持するのに問題なく機能します。

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);
  }
}

だから、私が言ったように、これは「標準」コンパイラで問題なく動作します。次に、読み込み時に、親クラスのインスタンスを取り込んでインスタンス化し、親を渡すコンストラクターを探すことを除いて、同様のことが起こります。

しかし!

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

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

4

1 に答える 1

0

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

于 2012-04-23T14:35:51.203 に答える