[英]Why does Android classloader allow reflective access to the public field of a package-private class from another package?
It seems that the Android application class loader allows to reflectively acquire a reference to the public static
field of a package-private class even from a different package (than the one the aforementioned class is defined in), while Sun JDK classloader for example doesn't. 似乎Android应用程序类加载器允许反射性地获取对包私有类的
public static
字段的引用,甚至来自不同的包(比上面定义的类的那个),而Sun JDK类加载器例如没有'吨。
More concretely, given the following class definition: 更具体地说,给定以下类定义:
package org.example.a
class PackagePrivateClass {
public static final Parcelable.Creator<PackagePrivateClass> CREATOR = generateCreator();
}
And the following code in a separate package: 以下代码在一个单独的包中:
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)
}
}
When executed on Sun JVM it throws an IllegalAccessException
on the last line: 在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)
...
However, when run on an Android device (5.1 Lollipop FWIW) it executes without throwing and creatorFieldRef.get(null)
actually returns a valid reference to the CREATOR
field. 但是,当在Android设备(5.1 Lollipop FWIW)上运行时,它会在不抛出的情况下执行,而
creatorFieldRef.get(null)
实际上会返回对CREATOR
字段的有效引用。
My question is : why is it the case ? 我的问题是:为什么会这样? Is it a bug or a feature of the Android classloader ??
它是Android类加载器的错误还是功能? (or, if applicable, what did I get wrong in my example ?)
(或者,如果适用的话,我的例子中出了什么问题?)
Seems that it is a bug in the android runtime which was fixed in this commit : 似乎是在这个提交中修复的android运行时中的一个错误:
Add access checks to Method and Field reflection.
将访问检查添加到方法和字段反射。
Prior to this commit it was possible to access fields via reflection in an unrestricted way or even set the value of final fields . 在此提交之前,可以通过不受限制的方式通过反射访问字段,甚至可以设置最终字段的值 。
The access check is now implemented in the runtime functions ValidateFieldAccess
and ValidateAccess
. 现在 ,在运行时函数
ValidateFieldAccess
和ValidateAccess
实现了访问检查。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.