it-swarm.com.de

Was ist der Sinn von "final class" in Java?

Ich lese gerade ein Buch über Java und es heißt, dass Sie die gesamte Klasse als final deklarieren können. Mir fällt nichts ein, wo ich das verwenden würde.

Ich bin gerade neu in der Programmierung und ich frage mich, ob Programmierer dies tatsächlich in ihren Programmen verwenden . Wenn ja, wann verwenden sie es, damit ich es besser verstehe und weiß, wann ich es verwenden soll.

Wenn Java objektorientiert ist und Sie eine Klasse als final deklarieren, stoppt es dann nicht die Idee, dass eine Klasse die Eigenschaften von Objekten hat?

488
newbie

Wenn ja, wann verwenden sie es, damit ich es besser verstehen kann und weiß, wann es verwendet wird.

Eine final-Klasse ist einfach eine Klasse, die nicht erweitert werden kann.

(Dies bedeutet nicht, dass alle Verweise auf Objekte der Klasse so wirken würden, als wären sie als final deklariert.) 

Wenn es sinnvoll ist, eine Klasse als endgültig zu deklarieren, wird in den Antworten auf diese Frage darauf hingewiesen:

Wenn Java objektorientiert ist und Sie eine Klasse final deklarieren, hört das dann nicht auf, dass Klasse die Eigenschaften von Objekten hat?

In gewissem Sinne ja.

Indem Sie eine Klasse als final kennzeichnen, deaktivieren Sie eine leistungsstarke und flexible Funktion der Sprache für diesen Teil des Codes. Einige Klassen sollten jedoch nicht (und in bestimmten Fällen can nicht) so konzipiert sein, dass sie Unterklassen auf eine gute Weise berücksichtigen. In diesen Fällen ist es sinnvoll, die Klasse als endgültig zu kennzeichnen, obwohl sie die OOP begrenzt. (Denken Sie jedoch daran, dass eine Abschlussklasse noch eine weitere nicht-Abschlussklasse erweitern kann.)


Zugehöriger Artikel: Java: Wann eine endgültige Klasse erstellt wird

449
aioobe

In Java können Elemente mit dem Modifizierer final nicht geändert werden!

Dies umfasst abschließende Klassen, abschließende Variablen und abschließende Methoden:

  • Eine Abschlussklasse kann nicht um eine andere Klasse erweitert werden
  • Eine letzte Variable kann keinem anderen Wert zugewiesen werden
  • Eine letzte Methode kann nicht überschrieben werden
167
andyqee

Ein Szenario, in dem final wichtig ist, wenn Sie aus Sicherheitsgründen die Vererbung einer Klasse verhindern möchten. Auf diese Weise können Sie sicherstellen, dass der von Ihnen ausgeführte Code kann nicht überschrieben werden von jemandem ausgeführt werden.

Ein anderes Szenario ist für die Optimierung: Ich denke daran, dass der Java-Compiler einige Funktionsaufrufe von finalen Klassen einleitet. Wenn Sie also a.x() aufrufen und a als final deklariert ist, wissen wir zur Kompilierzeit, was der Code sein wird, und können in die aufrufende Funktion integriert werden. Ich habe keine Ahnung, ob das tatsächlich gemacht wird, aber mit final ist es möglich.

28
Shay Rojansky

Das beste Beispiel ist 

öffentliche Abschlussklasse String

dies ist eine unveränderliche Klasse, die nicht erweitert werden kann. Natürlich gibt es mehr als nur die Finalisierung der Klasse als unveränderlich.

19
javadeveloper

Wenn Sie sich die Klassenhierarchie als Baum vorstellen (wie in Java), können abstrakte Klassen nur Verzweigungen sein und letzte Klassen sind nur Blätter. Klassen, die in keine dieser Kategorien fallen, können sowohl Zweige als auch Blätter sein.

Es gibt keine Verletzung von OO Prinzipien, final ist lediglich eine Symmetrie von Nizza.

In der Praxis möchten Sie final verwenden, wenn Ihre Objekte unveränderlich sein sollen oder wenn Sie eine API schreiben, um den Benutzern der API zu signalisieren, dass die Klasse nicht für die Erweiterung gedacht ist.

15
biziclop

Relevante Lektüre: Das Open-Closed-Prinzip von Bob Martin.

Schlüsselzitat:

Software-Entitäten (Klassen, Module, Funktionen usw.) sollten für .__ geöffnet sein. Erweiterung, aber für .__ geschlossen. Änderung.

Das Schlüsselwort final ist das Mittel, um dies in Java durchzusetzen, unabhängig davon, ob es für Methoden oder Klassen verwendet wird.

15

Das Schlüsselwort final selbst bedeutet, dass etwas endgültig ist und in keiner Weise geändert werden darf. Wenn eine Klasse als final markiert ist, kann sie weder erweitert noch untergeordnet werden. Aber die Frage ist, warum markieren wir eine Klasse final? IMO gibt es verschiedene Gründe:

  1. Standardization: Einige Klassen führen Standardfunktionen aus und sollen nicht modifiziert werden, z. Klassen, die verschiedene Funktionen ausführen, die sich auf String-Manipulationen oder mathematische Funktionen usw. beziehen.
  2. Sicherheitsgründe: Manchmal schreiben wir Klassen, die verschiedene Authentifizierungs- und Passwortfunktionen ausführen, und möchten nicht, dass sie von anderen Personen geändert werden. 

Ich habe gehört, dass die Markierungsklasse final die Effizienz verbessert, aber ehrlich gesagt konnte ich nicht finden, dass dieses Argument viel Gewicht trägt.

Wenn Java objektorientiert ist und Sie eine Klasse als final deklarieren, stimmt es nicht Stoppen Sie die Vorstellung, dass die Klasse die Eigenschaften von Objekten hat?

Vielleicht ja, aber manchmal ist das der beabsichtigte Zweck. Manchmal tun wir dies, um größere Sicherheitsvorteile usw. zu erreichen, indem wir die Erweiterbarkeit dieser Klasse opfern. Eine Abschlussklasse kann jedoch eine Klasse erweitern, wenn dies erforderlich ist.

Nebenbei sollten wir die Zusammensetzung der Vererbung vorziehen und das final-Schlüsselwort hilft tatsächlich bei der Durchsetzung dieses Prinzips.

9
i_am_zero

UM DAS FINAL-CLASS-PROBLEM ZU BEHEBEN:

Es gibt zwei Möglichkeiten, eine Klasse final zu machen. Die erste besteht darin, das Schlüsselwort final in der Klassendeklaration zu verwenden:

public final class SomeClass {
  //  . . . Class contents
}

Die zweite Möglichkeit, eine Klasse als final zu definieren, besteht darin, alle Konstruktoren als privat zu deklarieren:

public class SomeClass {
  public final static SOME_INSTANCE = new SomeClass(5);
  private SomeClass(final int value) {
  }

Wenn Sie es als final kennzeichnen, sparen Sie sich die Mühe, wenn Sie herausfinden, dass es sich tatsächlich um ein finales handelt. sieht auf den ersten Blick öffentlich aus.

public class Test{
  private Test(Class beanClass, Class stopClass, int flags)
    throws Exception{
    //  . . . snip . . . 
  }
}

Da der einzige Konstruktor der Klasse privat ist, kann diese Klasse leider nicht erweitert werden. Im Fall der Testklasse gibt es keinen Grund, dass die Klasse endgültig sein sollte. Die Test-Klasse ist ein gutes Beispiel dafür, wie implizite Abschlussklassen Probleme verursachen können.

Sie sollten es also als final markieren, wenn Sie eine Klasse als final definieren, indem Sie den Konstruktor als privat deklarieren.

5
mel3kings

final class kann verhindern, dass die öffentliche API beschädigt wird, wenn Sie neue Methoden hinzufügen

Nehmen Sie an, dass Sie in Version 1 Ihrer Base-Klasse Folgendes tun:

public class Base {}

und ein Kunde tut:

class Derived extends Base {
    public int method() { return 1; }
}

Wenn Sie in Version 2 dann eine method-Methode zu Base hinzufügen möchten:

class Base {
    public String method() { return null; }
}

es würde den Client-Code beschädigen.

Wenn wir stattdessen final class Base verwendet hätten, wäre der Client nicht in der Lage gewesen, zu erben, und der Zusatz der Methode würde die API nicht beschädigen.

Seien Sie vorsichtig, wenn Sie eine Klasse "final" machen. Wenn Sie einen Komponententest für eine letzte Klasse schreiben möchten, können Sie diese letzte Klasse nicht unterteilen, um die Abhängigkeitsbrechungsmethode "Unterklassen- und Überschreibungsmethode" zu verwenden, die in Michael C. Feathers 'Buch "Effektiv mit älterem Code arbeiten" beschrieben wird. . In diesem Buch sagte Feathers: "Im Ernst, es ist leicht zu glauben, dass Sealed und Final ein falscher Irrtum sind, dass sie niemals in Programmiersprachen aufgenommen werden sollten. Aber der eigentliche Fehler liegt bei uns. Wenn wir uns direkt darauf verlassen Bibliotheken, die außerhalb unserer Kontrolle liegen, bitten wir nur um Probleme. "

5
Ben Wu

Wenn die Klasse mit final markiert ist, bedeutet dies, dass die Struktur der Klasse nicht durch externe Elemente geändert werden kann. Wo dies am sichtbarsten ist, wenn Sie traditionelle polymorphe Vererbung durchführen, funktioniert class B extends A einfach nicht. Es ist im Grunde eine Möglichkeit, einige Teile Ihres Codes zu schützen (soweit vorhanden) .

Um zu verdeutlichen, dass das Markieren der Klasse final ihre Felder nicht als final kennzeichnet und als solches nicht die Objekteigenschaften schützt, sondern die tatsächliche Klassenstruktur.

5
Esko

In Java wird das letzte Schlüsselwort für die folgenden Gelegenheiten verwendet.

  1. Endvariablen
  2. Endgültige Methoden
  3. Abschlusskurse

In Java können final-Variablen nicht neu zugewiesen werden, final-Klassen können nicht erweitert werden und final-Methoden können nicht überschrieben werden.

3

Ein Vorteil, eine Klasse als endgültig zu halten: -

Die String-Klasse wird als final definiert, sodass niemand seine Methoden überschreiben und die Funktionalität ändern kann. Beispielsweise kann niemand die Funktionalität der length () - Methode ändern. Es wird immer die Länge einer Zeichenfolge zurückgegeben.

Der Entwickler dieser Klasse wollte, dass niemand die Funktionalität dieser Klasse ändert.

3
Rahul

Ja, manchmal möchten Sie dies jedoch aus Sicherheits- oder Geschwindigkeitsgründen. Es ist auch in C++ gemacht. Es kann sein, dass nicht dass für Programme anwendbar ist, sondern eher für Frameworks http://www.glenmccl.com/perfj_025.htm

3
James

Eine letzte Klasse ist eine Klasse, die nicht erweitert werden kann. Auch Methoden können als final deklariert werden, um anzuzeigen, dass sie nicht von Unterklassen überschrieben werden können. 

Wenn Sie verhindern, dass die Klasse subklassifiziert wird, kann dies besonders nützlich sein, wenn Sie APIs oder Bibliotheken schreiben und die Erweiterung zur Änderung des Basisverhaltens vermeiden möchten.

3
JuanZe

Die Android Looper-Klasse ist ein gutes praktisches Beispiel dafür. http://developer.Android.com/reference/Android/os/Looper.html

Die Looper-Klasse stellt bestimmte Funktionen bereit, die NICHT von einer anderen Klasse überschrieben werden sollen. Daher hier keine Unterklasse.

1
jaamit

betrachten Sie FINAL als das "Ende der Linie" - dieser Typ kann keinen Nachwuchs mehr produzieren. Wenn Sie es auf diese Weise sehen, gibt es eine Unmenge realer Szenarien, auf die Sie stoßen werden, und Sie müssen der Klasse eine Markierung für das Zeilenende markieren. Dies ist ein domänengesteuertes Design. Wenn Ihre Domäne verlangt, dass eine bestimmte ENTITY (Klasse) keine Unterklassen erstellen kann, markieren Sie sie als FINAL.

Ich sollte beachten, dass es nichts gibt, was Sie daran hindert, eine Klasse "sollte als letzte Klasse markiert werden" zu erben. Dies wird jedoch im Allgemeinen als "Missbrauch der Vererbung" klassifiziert und getan, da Sie häufig eine Funktion von der Basisklasse Ihrer Klasse erben möchten.

Der beste Ansatz besteht darin, sich die Domäne anzusehen und sie Ihre Konstruktionsentscheidungen bestimmen zu lassen.

1
Kingz

Wenn Sie möchten, dass niemand die Funktionalität der Methode ändern kann, können Sie sie als final deklarieren.

Beispiel: Dateipfad des Anwendungsservers für Download/Upload, Zeichenfolge basierend auf Versatz aufteilen. Solche Methoden können Sie als final deklarieren, damit diese Methodenfunktionen nicht geändert werden. Wenn Sie solche final-Methoden in einer separaten Klasse haben möchten, definieren Sie diese Klasse als final-Klasse. Die Final-Klasse verfügt also über alle final-Methoden, wobei die final-Methode in einer nicht finalen Klasse deklariert und definiert werden kann.

1
lok

Angenommen, Sie haben eine Employee-Klasse, die eine Methode greet hat. Wenn die greet-Methode aufgerufen wird, wird einfach Hello everyone! ausgegeben. Das ist also dieerwartetes Verhaltender greet-Methode

public class Employee {

    void greet() {
        System.out.println("Hello everyone!");
    }
}

Lassen Sie die GrumpyEmployee-Unterklasse Employee und überschreiben Sie die greet-Methode wie unten gezeigt. 

public class GrumpyEmployee extends Employee {

    @Override
    void greet() {
        System.out.println("Get lost!");
    }
}

Im folgenden Code sehen Sie sich die sayHello-Methode an. Sie nimmt Employee instance als Parameter und ruft die greet-Methode auf, in der Hoffnung, dass sie Hello everyone! sagt. Aber was wir bekommen, ist Get lost!. Diese Verhaltensänderung ist auf Employee grumpyEmployee = new GrumpyEmployee(); zurückzuführen.

public class TestFinal {
    static Employee grumpyEmployee = new GrumpyEmployee();

    public static void main(String[] args) {
        TestFinal testFinal = new TestFinal();
        testFinal.sayHello(grumpyEmployee);
    }

    private void sayHello(Employee employee) {
        employee.greet(); //Here you would expect a warm greeting, but what you get is "Get lost!"
    }
}

Diese Situation kannvermiedensein, wenn die Employee-Klasse final wurde. Stellen Sie sich vor, wie viel Chaos ein frecher Programmierer verursachen könnte, wenn String Class nicht als final deklariert wurde. 

1
Andy

Abschlussklassen können nicht erweitert werden. Wenn Sie also möchten, dass sich eine Klasse auf eine bestimmte Weise verhält und die Methoden nicht von jemandem überschrieben werden (mit möglicherweise weniger effizientem und bösartigerem Code), können Sie die gesamte Klasse als endgültige oder bestimmte Methode deklarieren, die Sie nicht sein möchten geändert. 

Da das Deklarieren einer Klasse die Instanziierung einer Klasse nicht verhindert, bedeutet dies nicht, dass die Klasse nicht die Eigenschaften eines Objekts besitzt. Es ist nur so, dass Sie sich an die Methoden halten müssen, wie sie in der Klasse deklariert werden. 

1
skhaapioloir

Der Abschlusskurs kann nicht weiter verlängert werden. Wenn eine Klasse nicht in Java vererbbar gemacht werden muss, können wir diesen Ansatz verwenden.

Wenn wir nur bestimmte Methoden in einer Klasse erstellen müssen, um nicht überschrieben zu werden, können wir ihnen nur das abschließende Schlüsselwort voranstellen. Dort ist die Klasse noch vererbbar.

0
G. Kith

Eine als final deklarierte Klasse, Variable oder Methode kann nicht geändert werden. 

Was ist wichtiger ist meine Meinung:

Ehrlich gesagt, glaube ich, dass ein Keyword final ein Fehler ist, da es einem Benutzer erlaubt, etwas zu definieren, das nichtfinal ist. Alles in Java sollte standardmäßig final sein, mit Ausnahme der Schnittstellenmethoden (durch seine Definition). Es war eine unglückliche Entscheidung, alle Instanzmethoden standardmäßig virtual (in Bezug auf c # ) zulassen zu lassen. Der Schlüssel besteht darin, den Benutzer zum Nachdenken zu zwingen und eine Methode explizit als virtual zu definieren. Dies würde ihn dazu bringen, sich zu fragen, ob diese Methode von anderen überschrieben werden sollte, ob really eine Notwendigkeit ist oder ihn dazu überredet, seinen Code neu zu gestalten.

0
Nikolas