简体   繁体   English

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

[英]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 . 现在 ,在运行时函数ValidateFieldAccessValidateAccess实现了访问检查。

暂无
暂无

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

相关问题 通过另一个包的公共子类使用包私有类的公共方法引用时出现IllegalAccessError - IllegalAccessError when using a public method reference of a package-private class through a public subclass from another package 包私有的Java默认类访问类似于public - Java default class access of package-private works like public 在公共类中使用包私有类 - Use package-private class in the public class 为什么我不能在另一个jar中访问包私有类(未密封)? - Why I cannot access a package-private class in another jar (NOT sealed)? 使用反射从外部包类设置包私有类的私有字段 - Set private field of package-private Class from outer package Class with reflection 为什么不能在同一个包中调用另一个类的包私有方法呢? - Why can't I call a package-private method of another class that's a subclass of a class in the same package? 为什么Java Reflection无法在另一个包中找到类的包私有构造函数? - Why can't Java Reflection find the package-private constructor of a class in another package? 有没有一种方法可以在Java中使用package-private来允许其他软件包访问? - Is there a way to use package-private in java to allow other packages access? 为什么我无法访问android.widget包中的package-private字段? - Why can't I access package-private fields in the android.widget package? 为什么Java编译器为package-private超类型中定义的公共方法添加可见性桥接方法? - Why does the Java compiler add visibility bridge methods for public methods defined in package-private super types?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM