反射在Android 2.2中没有完全实现



我有一些代码在2.3及以上版本中运行良好。然而,在2.2我得到一个NullPointerException当className被分配:

if(field.getType() == java.util.ArrayList.class)
   className = ((ParameterizedType)field.getGenericType()).toString();

编辑

我在android文档上做了一些窥探,发现一些方法直到API级别9才可用。然而,getType()、getGenericType()和ParameterizedType都被认为是在API级别1支持的。那么为什么这段代码不能工作呢?

字段文档:http://developer.android.com/reference/java/lang/reflect/Field.html

ParameterizedType docs: http://developer.android.com/reference/java/lang/reflect/ParameterizedType.html

编辑

我发现调用field.getGenericType()不会导致程序崩溃,但会无声地抛出一个com.sun.jdi.InvocationException。似乎从调用getGenericType()返回的类型是无效的?同样,这适用于2.3及以上版本,但为什么这个异常在2.2及以下版本被抛出和捕获?

这是一个已知的问题,这是Android漏洞跟踪器中的票证:issue 6636: NPE in org.apache.harmony.luni.lang.reflect.ListOfTypes

这个问题在Android 2.3中已经修复了,但是还没有被移植到早期的Android版本中,这就是为什么你在Android 2.2中看到崩溃。

更详细地说:如果你在Android 2.2上运行这段代码(你自己代码的扩展版本):

public class ReproduceBugActivity extends Activity {
  private static final String TAG = "ReproduceBugActivity";
  private ArrayList<Object> mArrayList;
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    try {
      String className = null;
      Field field = getClass().getDeclaredField("mArrayList");
      if (field.getType() == java.util.ArrayList.class)
        className = ((ParameterizedType)field.getGenericType()).toString();
      Log.i(TAG, "className = " + className);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

你会得到这样的异常:

java.lang.NullPointerException
   at org.apache.harmony.luni.lang.reflect.ListOfTypes.length(ListOfTypes.java:47)
   at org.apache.harmony.luni.lang.reflect.ImplForType.toString(ImplForType.java:83)
   at com.reproducebug.ReproduceBugActivity.onCreate(ReproduceBugActivity.java:23)

,因为上面提到的Java反射实现中的错误。在Android 2.3中,这个bug已经被修复了,你会在日志记录中看到:

I/ReproduceBugActivity(23449): className = java.util.ArrayList<java.lang.Object>

据我所知,您所看到的com.sun.jdi.InvocationException异常与此无关。

相关内容

  • 没有找到相关文章

最新更新