JavaRush /Java-Blog /Random-DE /So endgültig...
Алексей
Level 32

So endgültig...

Veröffentlicht in der Gruppe Random-DE
Es gibt ein Schlüsselwort in Java - final. Es kann auf Klassen, Methoden und Variablen (einschließlich Methodenargumente) angewendet werden. So endgültig... - 1Für eine Klasse bedeutet dies, dass die Klasse keine Unterklassen haben kann, d. h. Eine Vererbung ist verboten. Dies ist nützlich, wenn Sie immutable(unveränderliche) Objekte erstellen, beispielsweise eine Klasse, Stringdie als deklariert ist final.
public final class String{
}

class SubString extends String{ //Kompilierungsfehler
}
Es ist auch zu beachten, dass der Modifikator nicht auf abstrakte Klassen (mit dem Schlüsselwort abstract) angewendet werden kann, finalweil Dies sind sich gegenseitig ausschließende Konzepte. Denn eine Methode finalbedeutet, dass sie in Unterklassen nicht überschrieben werden kann. Dies ist nützlich, wenn die ursprüngliche Implementierung nicht überschrieben werden soll.
public class SuperClass{
    public final void printReport(){
        System.out.println("Report");
    }
}

class SubClass extends SuperClass{
    public void printReport(){  //Kompilierungsfehler
        System.out.println("MyReport");
    }
}
Für Variablen vom primitiven Typ bedeutet dies, dass der einmal zugewiesene Wert nicht mehr geändert werden kann. Für Referenzvariablen bedeutet dies, dass nach der Zuweisung eines Objekts die Referenz auf dieses Objekt nicht mehr geändert werden kann. Es ist wichtig! Der Link kann nicht geändert werden, aber der Status des Objekts kann geändert werden. Mit Java 8 erschien das Konzept - effectively final. Es gilt nur für Variablen (einschließlich Methodenargumente). Der Punkt ist, dass sich der Wert der Variablen trotz des offensichtlichen Fehlens des Schlüsselworts finalnach der Initialisierung nicht ändert. Mit anderen Worten: Sie können eine solche Variable durch ein Wort ersetzen, finalohne dass ein Kompilierungsfehler auftritt. effectively finalVariablen können in lokalen Klassen ( Local Inner Classes), anonymen Klassen ( Anonymous Inner Classes) und Streams (Stream-API) verwendet werden.
public void someMethod(){
    // Im folgenden Beispiel sind sowohl a als auch b effektiv endgültig, da die Werte einmal festgelegt werden:
    int a = 1;
    int b;
    if (a == 2) b = 3;
    else b = 4;
    // c ist NICHT effektiv endgültig, weil Wertänderungen
    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)); //Kompilierungsfehler
}
Jetzt lasst uns ein kleines Interview führen. Schließlich besteht das Ziel des JavaRush-Kurses darin, Java-Entwickler zu werden und einen interessanten und gut bezahlten Job zu bekommen. Also, fangen wir an.
  1. Was können Sie über ein Array sagen, wenn es deklariert ist final?

  2. Es ist bekannt, dass es sich um eine Klasse Stringhandelt immutable, die Klasse deklariert wird finalund der Wert der Zeichenfolge in einem Array gespeichert wird char, das mit dem Schlüsselwort markiert wird final.

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
Ist es möglich, den Wert eines Objekts zu ersetzen String(ohne den Verweis auf das Objekt zu ändern)? Das sind echte Interviewfragen. Und wie die Praxis zeigt, beantworten viele sie falsch. Es ist sehr wichtig, die Verwendung des Schlüsselworts zu verstehen final, insbesondere für Referenzvariablen. Während Sie nachdenken, ein kurzer Exkurs zum JavaRush-Team. Bitte fügen Sie in Ihrem Texteditor einen Block hinzu, der es Ihnen ermöglicht, den Inhalt auszublenden. Wenn Sie darauf klicken, wird dieser Inhalt angezeigt. Antworten:
  1. Weil Ein Array ist ein Objekt, was finalbedeutet, dass nach dem Zuweisen eines Verweises auf ein Objekt dieses nicht mehr geändert werden kann, der Zustand des Objekts jedoch geändert werden kann.

    final int[] array = {1,2,3,4,5};
    array[0] = 9;	//ok, weil Ändern Sie den Inhalt des Arrays - {9,2,3,4,5}
    array = new int[5]; //Kompilierungsfehler
  2. Ja, du kannst. Der Schlüssel liegt darin, die Verwendung des Stachelworts finalmit Objekten zu verstehen. Verwendet ReflectionAPI, um den Wert zu ersetzen.

import java.lang.reflect.Field;

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

        //Das Wertfeld in der String-Klasse abrufen
        Field field = value.getClass().getDeclaredField("value");
        //Lass es uns ändern
        field.setAccessible(true);
        //Neuen Wert festlegen
        field.set(value, "JavaRush".toCharArray());

        System.out.println(value);

        /* Вывод:
         * Old value
         * JavaRush
         */
    }
}
Bitte beachten Sie, dass nichts funktionieren würde, wenn wir versuchen würden, die letzte Variable eines primitiven Typs auf diese Weise zu ändern. Ich empfehle Ihnen, sich davon zu überzeugen: Erstellen Sie beispielsweise eine Java-Klasse mit final inteinem Feld und versuchen Sie, seinen Wert über die Reflection-API zu ändern. Allen viel Glück!
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION