matriz final en Java

El siguiente código en Java usa una matriz final de String y no hay dudas al respecto.

 final public class Main { public static final String[] CONSTANT_ARRAY = {"I", "can", "never", "change"}; public static void main(String[] args) { for (int x = 0; x < CONSTANT_ARRAY.length; x++) { System.out.print(CONSTANT_ARRAY[x] + " "); } } } 

Muestra la siguiente salida en la consola.

 I can never change 

El siguiente código también va sin ninguna pregunta.

 final public class Main { public static final String[] CONSTANT_ARRAY = {"I", "can", "never", "change"}; public static void main(String[] args) { //CONSTANT_ARRAY={"I", "can", "never", "change"}; //Error - can not assign to final variable CONSTANT_ARRAY. for (int x = 0; x < CONSTANT_ARRAY.length; x++) { System.out.print(CONSTANT_ARRAY[x] + " "); } } } 

Obviamente, la línea comentada causa el error especificado porque estamos tratando de reasignar la matriz final declarada de tipo String .


¿Qué pasa con el siguiente código?

 final public class Main { public static final String[] CONSTANT_ARRAY = {"I", "can", "never", "change"}; public static void main(String[] args) { CONSTANT_ARRAY[2] = "always"; //Compiles fine. for (int x = 0; x < CONSTANT_ARRAY.length; x++) { System.out.print(CONSTANT_ARRAY[x] + " "); } } } 

y muestra I can always change significa que podríamos modificar el valor de la matriz final de tipo String . ¿Podemos modificar la matriz completa de esta manera sin violar la regla de la final ?

final en Java afecta a la variable , no tiene nada que ver con el objeto que le está asignando.

 final String[] myArray = { "hi", "there" }; myArray = anotherArray; // Error, you can't do that. myArray is final myArray[0] = "over"; // perfectly fine, final has nothing to do with it 

Editar para agregar comentarios: tenga en cuenta que dije el objeto que le está asignando . En Java, una matriz es un objeto. Esto mismo se aplica a cualquier otro objeto:

 final List myList = new ArrayList(): myList = anotherList; // error, you can't do that myList.add("Hi there!"); // perfectly fine. 

Estás malinterpretando la implementación final. final aplica a la referencia de objeto de matriz, lo que significa que una vez que se inicia, la referencia nunca puede cambiar, pero la matriz puede ser poblada. “No está infringiendo las reglas”, ha especificado solo una regla sobre el cambio de referencia que funciona en consecuencia. Si desea que los valores tampoco cambien nunca, debe elegir listas inmutables, es decir,

 List items = Collections.unmodifiableList(Arrays.asList("I", "can", "never", "change")); 

Solo puede hacer que la referencia de matriz no se pueda cambiar. Si desea que los elementos no se puedan cambiar, debe usar una colección no modificable de algún tipo.

Cuando declara una matriz como final, puede cambiar los elementos en la matriz, sin embargo, no puede cambiar la referencia de esta matriz.

final solo garantiza la inmutabilidad de primitivos. Y también garantiza que una variable se asigna solo una vez. Si un objeto es mutable, puede cambiar el contenido del evento definido como final. Puede consultar colecciones inmutables para sus necesidades. Tales como Collections.unmodifiableList () http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#unmodifiableList(java.util.List )

La referencia al objeto de matriz es final (no puede cambiar, por ejemplo, en caso de que intente asociar un objeto de matriz de Java diferente (instancia de String []) a la misma variable final … obtendrá un error de tiempo de comstackción).

PERO los campos del objeto de matriz final en su ejemplo no son definitivos, por lo que puede modificar su valor. … mientras que el objeto Java que creó, CONSTANT_ARRAY, después de recibir un valor inicial, tendrá ese valor “para siempre” == hasta que se detenga la JVM. 🙂 Será la misma instancia de String Array “para siempre”.

Las variables finales en Java no son un gran problema, solo dedique algo de tiempo para digerir el tema / idea cuidadosamente. 🙂
Sugiero a todos aquellos que no están seguros de meditar sobre esta página, por ejemplo: https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4

Permítanme citar la parte respectiva:

Una vez que se ha asignado una variable final, siempre contiene el mismo valor. Si una variable final contiene una referencia a un objeto, entonces el estado del objeto se puede cambiar mediante operaciones en el objeto, pero la variable siempre se referirá a la mismo objeto.

Esto se aplica también a las matrices, porque las matrices son objetos; si una variable final contiene una referencia a una matriz, los componentes de la matriz pueden modificarse mediante operaciones en la matriz, pero la variable siempre se referirá a la misma matriz. ”

El valor de la variable CONSTANT_ARRAY no puede cambiar. Esa variable contiene una matriz (referencia a una). Sin embargo, el contenido de la matriz puede cambiar. Lo mismo sucede cuando declara cualquier tipo de variable final que no sea un tipo escalar simple (por ejemplo, un objeto).

Tenga cuidado de cómo nombra sus variables. 🙂 Llamarlo CONSTANT_ARRAY no hace que el contenido de la matriz sea incambiable.

Aquí hay una buena referencia: la última palabra sobre el final

  final int[] res; int[] res1; int[] res2 = new int[1]; res2[0]=20; res1=res2; res1=res2;//no error System.out.println("res1:"+res1[0]); res = res2;//only once //res = res2;//error already initialised res2[0]=30; System.out.println("res:"+res[0]); 

salida :: res1: 20 res: 30