2010-11-19 2 views
3

я изучал исходный код java.util.HashMap и я хотел бы видеть, насколько хорошо функция хэш-код распределяет ключа во внутреннем массиве Entry-х (, который представляет собой пакет частной переменной) .so я сделал пакет с именем java.util в моем проекте просто проверить погоду я могу обмануть компилятор думать, что это то же самое package.Surprisingly он работал, и я написал следующий код:доступа пакет-частные переменные, используя зарезервированное имя пакета

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

Вы можете попробовать либо добавить свою банку в путь к классам, либо , используя одобренный каталог .

Бывший:

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

И эффект, чтобы загрузить первые классы, которые есть в yourJar, даже верховные основные классы.

Более поздняя форма заключается в размещении в каталоге $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/

+0

Это немного запутанно. Что такое одобренный каталог? – Emil

+0

Из ссылки: * Механизм переопределения стандартов одобряет средства, с помощью которых более поздние версии классов и интерфейсов, которые реализуют одобренные стандарты или автономные технологии, могут быть включены в платформу Java. * Похоже, что 'java.util' не подходит для этого механизм. Я обновлю ответ – OscarRyz

6

Даже если есть возможность иметь свой класс в java.util упаковке (например, замена основной баночки или определения вашего загрузчика классов пользовательского например), вам лучше использовать отражение. Это просто и просто:

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

 Смежные вопросы

  • Нет связанных вопросов^_^