Можно ли изменить окончательную переменную пакета с помощью отражения?

1

Можно ли изменить окончательную переменную пакета посредством отражения?

Скажем, у меня это:

public class Widget {
  final int val = 23;
}

Можно ли изменить значение val через отражение, если оно станет доступным?

Если это так, можно ли предотвратить это, не используя диспетчера безопасности?

  • 0
    stackoverflow.com/questions/3301635/… помогает вам
  • 0
    Если так, есть ли способ предотвратить это без использования менеджера безопасности?
Показать ещё 4 комментария
Теги:
access-modifiers

3 ответа

2
Лучший ответ

Оказывается, изменение конечных членов приводит к тому, что полученные от отражения значения отличаются от значений, возвращаемых обычным кодом! Это довольно страшно.

import java.lang.reflect.Field;

public class Test {

    private static final class Widget {
        private final int val = 23;

        public int getVal() {
            return val;
        }
    }

    public static void main(String[] args) throws Exception {
        Widget w = new Widget ();

        Field m = Widget.class.getDeclaredField("val");

        m.setAccessible(true);

        m.set(w, 233);

        Field m1 = Widget.class.getDeclaredField("val");
        m1.setAccessible(true);


        System.out.println(m.get(w)); /// PRINT 233
        System.out.println(w.getVal()); /// PRINT 23
        System.out.println(m1.get(w)); /// PRINT 233

    }
}
  • 0
    Это очень странно! Нам нужно больше расследовать
4

ДА. Попробуйте этот код:

public static void main(String[] args) throws Exception {
    Widget w = new Widget ();

    Field m = Widget.class.getDeclaredField("val");

    m.setAccessible(true);

    m.set(w, 233);

    System.out.println(m.get(w)); /// PRINT 233
}
  • 0
    Но System.out.println(w.val); показывает 23 , а не 233 . Так что, если вы не делаете доступ через отражение ...
  • 0
    @TJCrowder круто. ОК, так как это работает? Почему поле, а не с помощью геттера?
Показать ещё 3 комментария
-1

Попробуй это.

 Widget() {
     checkPerMission();
  }
     private void checkPerMission() {
         Class self = sun.reflect.Reflection.getCallerClass(1);
          Class caller = sun.reflect.Reflection.getCallerClass(3);
         if (self != caller) {
             throw new java.lang.IllegalAccessError();
         }

 }
  • 0
    пожалуйста, добавьте комментарий, прежде чем сделать его отрицательным

Ещё вопросы

Сообщество Overcoder
Наверх
Меню