2017-01-03 2 views
-1

Итак, я обнаружил, как Change private static final field using Java reflection некоторое время назад и использовал его для изменения окончательных полей с отражением с тех пор, однако я тогда задался вопросом, почему я не мог применить ту же логику к типу для поля. Я придумалМожет отражать изменение объявленного типа поля

public static void changeFieldType(Field field, Class newType){ 
    try { 
     Field typeField = Field.class.getDeclaredField("type"); 
     typeField.setAccessible(true); 
     typeField.set(field, newType); 
    } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) { 
     LogUtil.printErr("Failed to edit field type for " + field.getName()); 
    } 
} 

Однако это привело меня к интересно, как это будет влиять заявление, если вы, скажем, установить тип для поля Object, когда он был первоначально ArrayList или какой-либо другой более высокий класс уровень. Будет ли это создавать внутренние ошибки в JVM или это значение просто клон данных JVM и его изменение не повлияет. Любой свет, который вы можете пролить на эту тему, очень ценится.

+1

короткий ответ: нет. невозможно изменить тип переменной, и невозможно изменить ее область действия (например, сделать ее статической) –

+1

Только инструментарий может работать, если JVM поддерживает его. Основные JVM не поддерживают это вообще. – Holger

ответ

2

Вы можете думать о значениях как о вещах, которые вы помещаете в ящики внутри ящика (ящик, представляющий весь объект, и каждый ящик внутри него, представляющий поле). Отражение позволяет изменять содержимое ящиков, но это не позволяет вам изменять форму любого окна или общую форму ящика. Структура класса фиксируется после его загрузки.

Есть способы изменить его на лету, поскольку он считывается из файла .class. Этот процесс известен как плетение байт-кода. Излишне говорить, что это немного сложнее (например, если вы меняете метод, чтобы взять int вместо длинного, тогда вам также необходимо изменить все сайты вызова этого метода для передачи в int вместо длинного) ,

0

Инструментарий может изменить тип, если класс еще не загружен. Как только класс загружен, изменение типа намного сложнее.

Использование Unsafe позволяет получить доступ к памяти по вашему желанию, заменяя int ссылкой на Object, но это полностью используется на ваш страх и риск.

Примечание: изменение типа ссылки от List до Object во время выполнения не изменило тип фактического объекта, на который делается ссылка.

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