modificadores modificador metodos metodo calificador acceso java final modifier

metodos - Añadir modificador final en tiempo de ejecución en Java



private final java (2)

Puede sonar un poco extraño, pero ¿es posible agregar el modificador final en tiempo de ejecución?

Tengo una variable que está marcada como public static int/short . En cierto momento quiero evitar que cambie su valor, y quiero mantener su accesibilidad como un valor estático estándar ( ClassName.field ).

public class Main { private static int a = 0; public static void addFinalMod(Field f) { Field modifiersField = null; try { modifiersField = Field.class.getDeclaredField("modifiers"); } catch (NoSuchFieldException e) { e.printStackTrace(); } modifiersField.setAccessible(true); try { modifiersField.setInt(f, f.getModifiers() & Modifier.FINAL); } catch (IllegalAccessException e) { e.printStackTrace(); } } public static void main(String[] args) { System.out.println(a); try { Field f = Main.class.getDeclaredField("a"); addFinalMod(f); } catch (NoSuchFieldException e) { e.printStackTrace(); } a = 10; //I was expecting error/exception here System.out.println(a); }

Salida:

0 10


En cierto punto quiero evitar cambiar su valor.

Hacer eso en la lógica de la aplicación. Hacer que la variable solo sea accesible a través de métodos. Mantenga una bandera de seguimiento de cualquier cambio en la variable. Una vez que haya aplicado el cambio o haya alcanzado el punto determinado , levante la bandera y lance una excepción para cualquier intento posterior de cambiar la variable.

final es una palabra clave / función de idioma para escribir su código fuente y evitar la reasignación de una variable en el código fuente. En tiempo de ejecución, no hace (casi) nada.


Utiliza un objeto inmutable:

public class Thing { private int value; public Thing(int value) { this.value = value; } public int getValue() { return this.value; } }

Luego simplemente reemplácelo cuando necesite modificación:

Thing x = Thing(1); // do some stuff x = Thing(2); // more stuff

Si estás pensando, "¡Pero entonces aún pueden modificar el valor reemplazando el objeto!" bueno, por supuesto La única forma de evitarlo es bloquear algún estado global (lo que en realidad es imposible si no es una constante), pero no estás usando un estado global, ¿verdad? El estado global es una cosa mala.

El estado global tiene un problema muy simple: hace que su código sea mucho menos reutilizable y más propenso a errores. El error propenso es especialmente cierto si está modificando ese estado global en tiempo de ejecución. "Oh, mierda, las cosas están sucediendo en el orden equivocado". No tienes idea de lo fácil que es eso. Tratar de rastrear el orden de los eventos es la razón por la cual el mutlithreading es tan difícil. En términos de reutilización, significa que no puede tener dos instancias independientes de la cosa, lo que a su vez implica que realmente no puede tener dos instancias de cualquier cosa que dependa de ella (al menos cuando resulta que necesita variar esta cosa después de todo).

Incluso si esto no es global, entonces este es un estado extraño en el que todos los que tienen que modificar su código (incluido usted) tendrán que estar conscientes y pensar a medida que realizan cambios. ¿Parece que va a hacer que cambiar las cosas sea más fácil o más difícil? (Pista: esta última). No te hagas esto a ti mismo ni a tus compañeros de trabajo. Hazlo más sencillo. Tome una lección del Zen de Python : "Simple es mejor que complejo".

Por lo tanto, si necesita un objeto inmutable, use un objeto inmutable. Si necesita un elemento global inmutable que no sea una constante, busque una mejor manera de organizar su código.