JavaRush /Blog Java /Random-ES /Así de definitivo...
Алексей
Nivel 32

Así de definitivo...

Publicado en el grupo Random-ES
Hay una palabra clave en java - final. Se puede aplicar a clases, métodos, variables (incluidos los argumentos del método). Así que final... - 1Para una clase, esto significa que la clase no puede tener subclases, es decir La herencia está prohibida. Esto es útil al crear immutableobjetos (inmutables), por ejemplo, una clase Stringdeclarada 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), finalporque Estos son conceptos mutuamente excluyentes. Porque un método finalsignifica 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 finalsin que se produzca un error de compilación. effectively finalLas 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.
  1. ¿ Qué se puede decir acerca de una matriz cuando se declara final?

  2. Se sabe que la clase Stringes immutable, la clase se declara final, el valor de la cadena se almacena en una matriz char, que se marca con la palabra clave final.

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:
  1. Porque una matriz es un objeto, lo que finalsignifica 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
  2. Sí tu puedes. La clave es comprender el uso de la palabra espinosa finalcon 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 intun campo e intente cambiar su valor a través de la API Reflection. ¡Buena suerte a todos!
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION