我怎样才能通过Android的反射实例化一个成员类 [英] How can I instantiate a member class through reflection on Android

查看:126
本文介绍了我怎样才能通过Android的反射实例化一个成员类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是应该保存任意对象图在保存/载入框架。这包括非静态内部类的实例。

I have a saving/loading framework that is supposed to save arbitrary object graphs. This includes instances of non-static nested classes.

嵌套类需要由它们的父类的创建它们的实例所拥有,而嵌套类​​知道它是属于什么情况下使用合成领域。

Nested classes require are owned by the instance of their parent class that created them, and the nested class knows what instance it belongs to using a synthetic field.

作为一个简单的例子,我present这个类:

As a simple example, I present this class:

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

在标准的编译器,下面的code的作品就好参加一个对象( myBar ),找到它的父(特定实例),并保持它的孩子一个参考:

On the "standard" compiler, the following code works just fine to take in an object (myBar), find its parent (a particular instance of Foo), and keep a reference of it with the child:

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

所以,就像我说的,这只是正常的对标准的编译器。然后,在加载时,类似的事情发生,但我找了一个构造函数在父类的一个实例,并创建实例,传递父。

So, like I said, this works just fine in on the "standard" compiler. Then at load time, something similar happens, except I look for a constructor that takes in an instance of the parent class and instantiate it, passing in the parent.

不过!

这不会对Android的虚拟机上工作。有没有合成领域,并在构造函数看上去都很正常,就像他们不参加父实例。

It doesn't work on the Android VM. There are no synthetic fields, and the constructors all look normal, like they don't take in a parent instance.

我是第SOL在这里?该虚拟机显然不喜欢我的做法。有什么我可以在这里做,而不需要内部类要知道,他们需要一个参考保存到它们的父类的实例?

Am I SOL here? This VM obviously does not like my approach. Is there anything I can do here without requiring inner classes to know that they need to save a reference to their parent class instance?

推荐答案

好了,原来我叫错了树。我介绍的方法很完善Android上一样好,其他地方。问题是,课堂上,我是想在这种情况下,实例化是一个的静态的内部类。因此,尽管这是一个的成员的类,它没有提及它的外部类。我只需要检查如果(!Modifier.isStatic(objectClass.getModifiers()))之前寻找一个复合构造/场。

Okay, turns out I was barking up the wrong tree. The method I've outlined works perfectly well on Android just as well as anywhere else. The problem was that the class I was trying to instantiate in this case was a static internal class. So, while it was a member class, it didn't have a reference to its outer class. I just have to check if (!Modifier.isStatic(objectClass.getModifiers())) before looking for a synthetic constructor/field.

这篇关于我怎样才能通过Android的反射实例化一个成员类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆