似乎
Android应用程序类加载器允许反射性地获取对包私有类的公共静态字段的引用,即使从不同的包(不同于上述类被定义的包),而Sun JDK类加载器例如不是’吨.
更具体地说,给出以下类定义:
package org.example.a class PackagePrivateClass { public static final Parcelable.Creator<PackagePrivateClass> CREATOR = generateCreator(); }
以下代码在一个单独的包中:
package org.example.b public class TestClass { public void testMethod() { final Class classRef = Class.forName("org.example.a.PackagePrivateClass"); final Field creatorFieldRef = classRef.getField("CREATOR"); creatorFieldRef.get(null); // throws here (unless on Android) } }
在Sun JVM上执行时,它会在最后一行引发一个IllegalAccessException:
java.lang.IllegalAccessException: Class org.example.b.TestClass can not access a member of class org.example.a.PackagePrivateClass with modifiers "public static final" at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102) ...
但是,当在Android设备(5.1 Lollipop FWIW)上运行时,它会执行而不会抛出,并且creatorFieldRef.get(null)实际上返回到CREATOR字段的有效引用.
解决方法
似乎这是在
commit中修复的android运行时的错误:
Add access checks to Method and Field reflection.
在此提交之前,可以通过反射来以不受限制的方式访问字段,甚至可以设置the value of final fields.