繁体   English   中英

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

[英]Why does Android classloader allow reflective access to the public field of a package-private class from another package?

似乎Android应用程序类加载器允许反射性地获取对包私有类的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类加载器的错误还是功能? (或者,如果适用的话,我的例子中出了什么问题?)

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

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

在此提交之前,可以通过不受限制的方式通过反射访问字段,甚至可以设置最终字段的值

现在 ,在运行时函数ValidateFieldAccessValidateAccess实现了访问检查。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM