为什么Android类加载器允许从另一个包reflection访问包 – 私有类的公共字段?

看起来,Android应用程序类加载器允许从一个不同的包(不同于前面提到的类定义的包)中reflection地获取对包 – 私有类的public static字段的引用,而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域的有效引用。

我的问题是:为什么是这样? 这是一个错误或Android类加载器的function? (或者,如果适用的话,在我的例子中我错了什么?)

Solutions Collecting From Web of "为什么Android类加载器允许从另一个包reflection访问包 – 私有类的公共字段?"

似乎这是在这个提交中修复的Android运行时的错误:

将访问检查添加到方法和字段reflection。

在这个提交之前,可以通过无限制地reflection来访问字段,甚至可以设置最终字段的值 。

访问检查现在在运行时函数ValidateFieldAccessValidateAccess