CodeGym /Java-Blog /Random-DE /Lassen Sie uns über das endgültige Schlüsselwort in Java ...
Autor
Oleksandr Miadelets
Head of Developers Team at CodeGym

Lassen Sie uns über das endgültige Schlüsselwort in Java sprechen

Veröffentlicht in der Gruppe Random-DE
Java hat dieses Schlüsselwort – final. Es kann auf Klassen, Methoden und Variablen (einschließlich Methodenparameter) angewendet werden. Für eine Klasse bedeutet das Schlüsselwort final, dass die Klasse keine Unterklassen haben kann, dh die Vererbung ist verboten... Dies ist nützlich, wenn unveränderliche (unveränderliche) Objekte erstellt werden. Beispielsweise wird die String-Klasse als final deklariert.

    public final class String {
    }
    
    class SubString extends String { // Compilation error
    }
Ich sollte auch beachten, dass der letzte Modifikator nicht auf abstrakte Klassen (solche mit dem Schlüsselwort abstract) angewendet werden kann, da es sich dabei um sich gegenseitig ausschließende Konzepte handelt. Für eine endgültige Methode bedeutet der Modifikator, dass die Methode in Unterklassen nicht überschrieben werden kann. Dies ist nützlich, wenn wir die Änderung der ursprünglichen Implementierung verhindern möchten.

    public class SuperClass {
        public final void printReport() {
            System.out.println("Report");
        }
    }

    class SubClass extends SuperClass { 
        public void printReport() { //Compilation error
            System.out.println("MyReport");
        }
    }
Bei Variablen eines primitiven Typs bedeutet das Schlüsselwort final, dass der einmal zugewiesene Wert nicht mehr geändert werden kann. Bei Referenzvariablen bedeutet dies, dass Sie nach der Zuweisung eines Objekts die Referenz auf dieses Objekt nicht mehr ändern können. Das ist wichtig! Die Referenz kann nicht geändert werden, aber der Status des Objekts kann geändert werden. Mit Java 8 wurde ein neues Konzept eingeführt: effektiv endgültig. Es gilt nur für Variablen (einschließlich Methodenparameter). Die Quintessenz ist, dass sich der Wert der Variablen nach der Initialisierung trotz des offensichtlichen Fehlens des Schlüsselworts final nicht ändert. Mit anderen Worten: Das Schlüsselwort final kann ohne Kompilierungsfehler auf eine solche Variable angewendet werden. Tatsächlich können endgültige Variablen innerhalb lokaler Klassen (lokale innere Klassen), anonymer Klassen (anonyme innere Klassen) und Streams (Stream-API) verwendet werden.

        public void someMethod() {
            // In the example below, both a and b are effectively final, since they are assigned values only once:
            int a = 1;
            int b;
            if (a == 2) b = 3;
            else b = 4;
            // c is NOT effectively final since its value changes
            int c = 10;
            c++;
            
            Stream.of(1, 2).forEach(s-> System.out.println(s + a)); // OK
            Stream.of(1, 2).forEach(s-> System.out.println(s + c)); // Compilation error
        }
Jetzt lasst uns ein kleines Interview führen. Schließlich besteht das Ziel des CodeGym-Kurses darin, Java-Entwickler zu werden und einen interessanten und gut bezahlten Job zu finden. Also, fangen wir an.
  1. Was können wir über ein Array sagen, das als endgültig deklariert ist?

  2. Wir wissen, dass die String-Klasse unveränderlich ist: Die Klasse wird als endgültig deklariert. Ein String-Wert wird in einem char-Array gespeichert, das mit dem Schlüsselwort final gekennzeichnet ist.


public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

Können wir den Wert eines String-Objekts ersetzen (ohne den Verweis auf das Objekt zu ändern)? Das sind echte Interviewfragen. Und die Praxis zeigt, dass viele Kandidaten sie nicht richtig beantworten. Es ist sehr wichtig zu verstehen, wie das Schlüsselwort final verwendet wird, insbesondere für Referenzvariablen. Während Sie darüber nachdenken, werde ich eine kleine Bitte an das CodeGym-Team richten. Bitte geben Sie dem Texteditor die Möglichkeit, einen Block hinzuzufügen, dessen Inhalt angezeigt/ausgeblendet werden kann, wenn Sie darauf klicken. Antworten:
  1. Ein Array ist ein Objekt, daher bedeutet das Schlüsselwort final, dass die Referenz nicht mehr geändert werden kann, sobald eine Referenz auf das Array zugewiesen wurde. Das heißt, Sie können den Status des Objekts ändern.

    
            final int[] array = {1, 2, 3, 4, 5};
            array[0] = 9;	 // OK, because we're changing the contents of the array: {9, 2, 3, 4, 5}
            array = new int[5]; // Compilation error
    
  2. Ja wir können. Die Hauptsache ist, zu verstehen, was das Schlusswort thorny bedeutet, wenn es mit Objekten verwendet wird. Die Reflection API kann zum Ersetzen von Werten verwendet werden.


import java.lang.reflect.Field;

class B {
    public static void main(String[] args) throws Exception {
        String value = "Old value";
        System.out.println(value);

        // Get the String class's value field
        Field field = value.getClass().getDeclaredField("value");
        // Make it mutable
        field.setAccessible(true);
        // Set a new value
        field.set(value, "CodeGym".toCharArray());

        System.out.println(value);

        /* Output:
         * Old value
         * CodeGym
         */
    }
}
Bitte beachten Sie, dass nichts passiert wäre, wenn wir versucht hätten, die letzte Variable eines primitiven Typs auf diese Weise zu ändern. Ich schlage vor, dass Sie sich selbst davon überzeugen: Erstellen Sie beispielsweise eine Java-Klasse mit einem finalen int-Feld und versuchen Sie, seinen Wert mithilfe der Reflection-API zu ändern. Allen viel Glück!
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION