使用保留包名访问包 - 私有变量

时间:2010-11-19 12:03:20

标签: java access-modifiers

我正在研究java.util.HashMap的源代码,我想看看哈希码函数在Entry的内部数组中分配密钥的效果如何(是一个包私有变量)。所以我在我的项目中创建了一个名为java.util的包只是为了检查天气我可以欺骗编译器认为它是相同的包。令人惊讶的是它有效并且我编写了以下代码:

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));
    }
}

它已成功编译但在运行时它给出了一个例外:

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或者是否有其他替代方法(可能使用反射)?

2 个答案:

答案 0 :(得分:6)

即使有一个选项让你的类在java.util包中(例如替换核心jar或定义你的自定义类加载器),你最好使用反射。它简单明了:

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

答案 1 :(得分:2)

您可以尝试使用背书目录在类路径中预先设置jar或

前者:

java -Xbootclasspath/p:youJarHere.jar  ..... 

效果是,首先加载你在theJar中的类,甚至覆盖核心类。

后面的表格是在您的$JAVA_HOME/lib/endorsed目录中放置类/罐子,它具有类似的效果。

我几年没有使用过这些,但是我用它们一次来替换核心类(CORBA包中的东西或类似的东西)。

尝试一下,让我们知道它是否有效。

这里有一些链接:

http://blogs.sourceallies.com/2010/02/replacing-and-patching-java-application-and-core-classes/

http://download.oracle.com/javase/6/docs/technotes/guides/standards/