Hay una palabra clave en java -
final
. Se puede aplicar a clases, métodos, variables (incluidos los argumentos del método). Para una clase, esto significa que la clase no puede tener subclases, es decir La herencia está prohibida. Esto es útil al crear immutable
objetos (inmutables), por ejemplo, una clase String
declarada como final
.
public final class String{
}
class SubString extends String{ //Error de compilación
}
También cabe señalar que el modificador no se puede aplicar a clases abstractas (con la palabra clave abstract
), final
porque Estos son conceptos mutuamente excluyentes. Porque un método final
significa que no se puede anular en subclases. Esto es útil cuando queremos que no se anule la implementación original.
public class SuperClass{
public final void printReport(){
System.out.println("Report");
}
}
class SubClass extends SuperClass{
public void printReport(){ //Error de compilación
System.out.println("MyReport");
}
}
Para variables de tipo primitivo, esto significa que una vez asignado, el valor no se puede cambiar. Para las variables de referencia, esto significa que una vez que se asigna un objeto, la referencia a ese objeto no se puede cambiar. ¡Es importante! El enlace no se puede cambiar, pero se puede cambiar el estado del objeto. Con Java 8 apareció el concepto: effectively final
. Solo se aplica a variables (incluidos los argumentos del método). El punto es que a pesar de la obvia ausencia de la palabra clave final
, el valor de la variable no cambia después de la inicialización. En otras palabras, puede sustituir una palabra por dicha variable final
sin que se produzca un error de compilación. effectively final
Las variables se pueden utilizar dentro de clases locales ( Local Inner Classes
), clases anónimas ( Anonymous Inner Classes
), transmisiones (Stream API).
public void someMethod(){
// En el siguiente ejemplo, tanto a como b son efectivamente definitivos, ya que los valores se establecen una vez:
int a = 1;
int b;
if (a == 2) b = 3;
else b = 4;
// c NO es efectivamente final porque cambios de valor
int c = 10;
c++;
Stream.of(1, 2).forEach(s-> System.out.println(s + a)); //Ок
Stream.of(1, 2).forEach(s-> System.out.println(s + c)); //Error de compilación
}
Ahora hagamos una pequeña entrevista. Después de todo, el objetivo de realizar el curso JavaRush es convertirse en desarrollador de Java y conseguir un trabajo interesante y bien remunerado. Vamos a empezar.
-
¿ Qué se puede decir acerca de una matriz cuando se declara
final
? -
Se sabe que la clase
String
esimmutable
, la clase se declarafinal
, el valor de la cadena se almacena en una matrizchar
, que se marca con la palabra clavefinal
.
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
¿Es posible reemplazar el valor de un objeto String
(sin cambiar la referencia al objeto)? Estas son preguntas reales de la entrevista. Y como muestra la práctica, muchos responden incorrectamente. Es muy importante comprender el uso de la palabra clave final
, especialmente para variables de referencia. Mientras piensa, una breve digresión sobre el equipo de JavaRush. Agregue un bloque en su editor de texto que le permita ocultar el contenido y, cuando haga clic en él, muestre este contenido. Respuestas:
-
Porque una matriz es un objeto, lo que
final
significa que después de asignar una referencia a un objeto, ya no se puede cambiar, pero se puede cambiar el estado del objeto.final int[] array = {1,2,3,4,5}; array[0] = 9; //bien, porque cambiar el contenido de la matriz - {9,2,3,4,5} array = new int[5]; //Error de compilación
-
Sí tu puedes. La clave es comprender el uso de la palabra espinosa
final
con los objetos. Utiliza ReflectionAPI para reemplazar el valor.
import java.lang.reflect.Field;
class B {
public static void main(String[] args) throws Exception {
String value = "Old value";
System.out.println(value);
//Obtener el campo de valor en la clase String
Field field = value.getClass().getDeclaredField("value");
//Vamos a cambiarlo
field.setAccessible(true);
// Establecer nuevo valor
field.set(value, "JavaRush".toCharArray());
System.out.println(value);
/* Вывод:
* Old value
* JavaRush
*/
}
}
Tenga en cuenta que si intentáramos cambiar la variable final de un tipo primitivo de esta manera, nada funcionaría. Le sugiero que se convenza de esto: cree una clase Java, por ejemplo, con final int
un campo e intente cambiar su valor a través de la API Reflection. ¡Buena suerte a todos!
GO TO FULL VERSION