Java reflection private final field

asaskevich / MainSandBox.java

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

package sandbox ;
import java . lang . reflect . Field ;
import java . lang . reflect . Modifier ;
public class MainSandBox
public static void main ( String [] args ) throws Exception
Example ex = new Example ();
// Change private modifier to public
Field f = ex . getClass (). getDeclaredField ( «id» );
f . setAccessible ( true );
// Remove final modifier
Field modifiersField = Field . class . getDeclaredField ( «modifiers» );
modifiersField . setAccessible ( true );
modifiersField . setInt ( f , f . getModifiers () & ~ Modifier . FINAL );
// Get and set field value
Integer old_value = ( Integer ) f . get ( ex );
f . set ( ex , 20 );
Integer new_value = ( Integer ) f . get ( ex );
// OUTPUT
System . out . println ( «ex1: \n » + old_value + » \n » + new_value );
Example ex2 = new Example ();
Field f2 = ex2 . getClass (). getDeclaredField ( «id» );
f2 . setAccessible ( true );
// Get and set field value
Integer old_value_2 = ( Integer ) f2 . get ( ex2 );
System . out . println ( «ex2: \n » + old_value_2 );
>
>
class Example
private final int id = 10 ;
>

Источник

Изменение приватного статического финального поля с помощью Java Reflection

В Java, когда поле объявлено как private static final, это означает, что оно может быть установлено только один раз и не может быть изменено после его инициализации.

В Java, когда поле объявлено как private static final , это означает, что оно может быть установлено только один раз и не может быть изменено после его инициализации. Однако, иногда возникает необходимость изменить это поле во время выполнения программы. Одним из способов это сделать является использование Java Reflection.

Предположим, у нас есть класс MyClass с private static final полем MY_CONST :

Попытка изменить MY_CONST напрямую вызовет ошибку компиляции, поскольку это поле объявлено как final .

MyClass.MY_CONST = "New Value"; // Ошибка компиляции

Вместо этого, можно использовать Java Reflection для обхода этого ограничения. Ниже приведен код, который показывает, как это можно сделать:

Field field = MyClass.class.getDeclaredField("MY_CONST"); field.setAccessible(true); Field modifiersField = Field.class.getDeclaredField("modifiers"); modifiersField.setAccessible(true); modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); field.set(null, "New Value");

Таким образом, первые две строки получают ссылку на поле MY_CONST и делают его доступным. Следующие две строки убирают модификатор final у поля. В последней строке устанавливается новое значение для MY_CONST .

Однако, стоит отметить, что использование Java Reflection для изменения private static final полей — это плохая практика, которую следует избегать. Это может привести к неожиданным и труднообнаруживаемым ошибкам, нарушает принципы инкапсуляции и может нарушить безопасность. Этот метод следует использовать только в крайних случаях, когда нет других решений.

Источник

asaskevich / MainSandBox.java

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

package sandbox ;
import java . lang . reflect . Field ;
import java . lang . reflect . Modifier ;
public class MainSandBox
public static void main ( String [] args ) throws Exception
Example ex = new Example ();
// Change private modifier to public
Field f = ex . getClass (). getDeclaredField ( «id» );
f . setAccessible ( true );
// Remove final modifier
Field modifiersField = Field . class . getDeclaredField ( «modifiers» );
modifiersField . setAccessible ( true );
modifiersField . setInt ( f , f . getModifiers () & ~ Modifier . FINAL );
// Get and set field value
Integer old_value = ( Integer ) f . get ( ex );
f . set ( ex , 20 );
Integer new_value = ( Integer ) f . get ( ex );
// OUTPUT
System . out . println ( «ex1: \n » + old_value + » \n » + new_value );
Example ex2 = new Example ();
Field f2 = ex2 . getClass (). getDeclaredField ( «id» );
f2 . setAccessible ( true );
// Get and set field value
Integer old_value_2 = ( Integer ) f2 . get ( ex2 );
System . out . println ( «ex2: \n » + old_value_2 );
>
>
class Example
private final int id = 10 ;
>

Источник

Change private static final field using Java reflection

Also I fixed an issue with override which the previous solutions seem to miss. However use this very carefully, only when there’s no other good solution.

Assuming no SecurityManager is preventing you from doing this, you can use setAccessible to get around private and resetting the modifier to get rid of final , and actually modify a private static final field.

import java.lang.reflect.*; public class EverythingIsTrue < static void setFinalStatic(Field field, Object newValue) throws Exception < field.setAccessible(true); Field modifiersField = Field.class.getDeclaredField("modifiers"); modifiersField.setAccessible(true); modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); field.set(null, newValue); >public static void main(String args[]) throws Exception < setFinalStatic(Boolean.class.getField("FALSE"), true); System.out.format("Everything is %s", false); // "Everything is true" >> 

Assuming no SecurityException is thrown, the above code prints «Everything is true» .

What’s actually done here is as follows:

  • The primitive boolean values true and false in main are autoboxed to reference type Boolean «constants» Boolean.TRUE and Boolean.FALSE
  • Reflection is used to change the public static final Boolean.FALSE to refer to the Boolean referred to by Boolean.TRUE
  • As a result, subsequently whenever a false is autoboxed to Boolean.FALSE , it refers to the same Boolean as the one refered to by Boolean.TRUE
  • Everything that was «false» now is «true»
Оцените статью