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 虚拟机。没有合成字段,构造函数看起来都很正常,就像它们不接受父实例一样。

我在这里吗?这个虚拟机显然不喜欢我的方法。我可以在这里做些什么而不需要内部类知道他们需要保存对其父类实例的引用?

4

1 回答 1

0

好吧,原来我叫错树了。我概述的方法在 Android 和其他任何地方都非常有效。问题是在这种情况下我试图实例化的类是一个静态内部类。因此,虽然它是一个成员类,但它没有对其外部类的引用。我只需要if (!Modifier.isStatic(objectClass.getModifiers()))在寻找合成构造函数/字段之前进行检查。

于 2012-04-23T14:35:51.203 回答