【问题标题】:Is it possible to bypass constructors when instantiating objects in Android在Android中实例化对象时是否可以绕过构造函数
【发布时间】:2010-06-25 21:17:09
【问题描述】:

Android 是否有任何方法可以在不调用任何构造函数的情况下实例化对象?

在 Java 中,Sun 有 sun.reflect.ReflectionFactory.getReflectionFactory().newConstructorForSerialization(),在 .Net 中有 System.Runtime.Serialization.FormatterServices.GetUninitializedObject(),但我无法做到在 Android 平台上找到类似的东西。

【问题讨论】:

  • 我真的很想知道这样的用例是什么。
  • 您的目标是反序列化可以说只有非空构造函数的对象吗?这是一个有趣的请求。
  • @Rich,Anthony,原因与序列化基础设施相同。我在 oodb 中工作,一旦我们实例化对象,我们就设置它的字段,所以调用构造函数至少是浪费时间/资源。在最坏的情况下,我们可能没有可用的构造函数(所有可用的构造函数在调用时都可能抛出空值/默认值)
  • @Quintin Robinson:基本上我们根本不关心这个类是否有任何构造函数。如果可能的话,最好绕过调用任何构造函数。

标签: android constructor objectinstantiation


【解决方案1】:

在查看 Android 源代码后,我们找到了一种使用 ObjectInputStream#newInstance() 静态方法来实现此目的的方法。

private Object newInstanceSkippingConstructor(final Class clazz) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException,     InvocationTargetException {

    Method newInstance = ObjectInputStream.class.getDeclaredMethod("newInstance", Class.class, Class.class);
    newInstance.setAccessible(true);
    return newInstance.invoke(null, clazz, Object.class);

}

【讨论】:

  • 现在已经过时了吗?我正在使用 API 19,据我所知,没有 ObjectInputStream.newInstance(Class, Class) 方法。有其他选择吗?
  • 嘿,在Android源代码中看起来这个方法确实被删除了。由于我不再使用此代码,我不知道是否有其他选择。 ObjectInputStream 中的代码依赖于 Class.newInstance(),根据文档,它确实调用了ctors。
【解决方案2】:

您可以使用 JNI AllocObject 函数从本机代码执行此操作。见the JNI Spec。调用本机代码将比调用无操作构造函数更昂贵,但可能比调用抛出异常的构造函数更便宜。

我不知道是否有其他方法可以做到这一点。什么都没有向我扑来。

【讨论】:

    【解决方案3】:

    我不这么认为,但是 Android 平台确实在 java.lang.reflect.* 中包含 Java 反射 API,因此使用 Java 反射 API 的任何事情在 Android 中都是可能的

    【讨论】:

    • 确实,我注意到了那个包,但正如我所说,我找不到任何东西来实现我的目标:(
    【解决方案4】:

    我发现了一个可以通过构造函数绕过来处理 OBJ 初始化的库 http://objenesis.org/index.html 他们对不同的 API 有不同的方法。 他们的 API 17 和 18+ impl 与当前建议的答案略有不同。此外,Android N+ 正在使用一种叫做 Unsafe 的东西,应该由新的 JVM 实现 http://mishadoff.com/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/

    【讨论】:

      猜你喜欢
      • 2014-09-09
      • 2013-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多