如何通过Android上的反射实例化成员类

时间:2012-04-20 21:05:01

标签: java android reflection inner-classes

我有一个保存/加载框架,可以保存任意对象图。这包括非静态嵌套类的实例。

嵌套类require由其创建它们的父类的实例拥有,嵌套类使用合成字段知道它属于哪个实例。

作为一个简单的例子,我提出了这个课程:

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显然不喜欢我的方法。有什么我可以做的,而不需要内部类知道他们需要保存对其父类实例的引用吗?

1 个答案:

答案 0 :(得分:0)

好的,事实证明我正在咆哮着错误的树。我概述的方法在Android上以及其他任何地方都能很好地运行。问题是我在这种情况下尝试实例化的类是 static 内部类。因此,虽然它是成员类,但它没有对其外部类的引用。我只需要在查找合成构造函数/字段之前检查if (!Modifier.isStatic(objectClass.getModifiers()))