使用保留的软件包名称访问软件包专用变量 [英] Access package-private variables using reserved package name

查看:90
本文介绍了使用保留的软件包名称访问软件包专用变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究 java.util.HashMap ,我想看看hashcode函数如何很好地分配密钥的在 Entry 's(这是一个包私有变量)的内部数组中。所以我制作了一个名为 java的包.util 在我的项目中只是为了检查天气,我可以使编译器认为它是同一个软件包。令人惊讶的是它起作用了,我编写了以下代码:

I was studying the source code of java.util.HashMap and I wanted to see how well the hashcode function distributes the key's in the internal array of Entry's(which is a package private variable).So I made a package named java.util in my project just to check weather I can fool the compiler to think it's the same package.Surprisingly it worked and I wrote the following code:

package java.util;

public class HashMapExt<K, V> extends HashMap<K, V> implements Map<K, V> {

    public static void main(String[] args) {
        HashMapExt<Integer, String> mp = new HashMapExt<Integer, String>();
        mp.put(1, "Hello");
        mp.put(2, "Map");
        mp.put(3, "Extention");
        mp.printData();
    }

    void printData() {

        System.out.println(Arrays.toString(table));
    }
}

编译成功,但是运行时出现异常:

It compiled successfully but while running it gave an exception:

Exception in thread "main" java.lang.SecurityException: Prohibited package name: java.util
    at java.lang.ClassLoader.preDefineClass(Unknown Source)
    at java.lang.ClassLoader.defineClass(Unknown Source)
    at java.security.SecureClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.access$000(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClassInternal(Unknown Source)

现在的问题是,是否可以更改默认的安全模型,以便我可以访问内部变量 table 或是否有其他替代方法(也许通过使用反射)?

Now the question is, is it possible to change the default security model so that I can access the internal variable table or is there any other alternative (maybe by using reflection) ?

推荐答案

即使可以选择将类放在 java.util 包中(例如替换核心jar或定义例如您的自定义类加载器),则最好使用反射。这很简单明了:

Even if there is an option to have your class in the java.util package (like replacing the core jar or defining your custom class loader for example), you'd better use reflection. It is simple and straightforward:

Field tableField = HashMap.class.getDeclaredField("table");
tableField.setAccessible(true);
Map.Entry[] entries = (Map.Entry[]) tableField.get(yourMap);

这篇关于使用保留的软件包名称访问软件包专用变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆