Was entspricht Javas Finale in C #?

559

Was entspricht Java finalin C #?

Nosrama
quelle
131
Ein Kommentar zum Klassenbesten mit der Aufschrift "Wenn Sie diese Klasse überschreiben, werden Sie entlassen!" (Natürlich ist es ein Witz :)
Hemant

Antworten:

861

Das finalSchlüsselwort wird in Java mehrfach verwendet. Es entspricht sowohl die sealedund readonlySchlüsselwort in C #, je nach Kontext , in dem sie verwendet wird.

Klassen

So verhindern Sie Unterklassen (Vererbung von der definierten Klasse):

Java

public final class MyFinalClass {...}

C #

public sealed class MyFinalClass {...}

Methoden

Verhindern Sie das Überschreiben einer virtualMethode.

Java

public class MyClass
{
    public final void myFinalMethod() {...}
}

C #

public class MyClass : MyBaseClass
{
    public sealed override void MyFinalMethod() {...}
}

Wie Joachim Sauer betont, besteht ein bemerkenswerter Unterschied zwischen den beiden Sprachen darin, dass Java standardmäßig alle nicht statischen Methoden als virtualkennzeichnet, während C # sie als kennzeichnet sealed. Daher müssen Sie das sealedSchlüsselwort in C # nur verwenden, wenn Sie das weitere Überschreiben einer Methode stoppen möchten, die virtualin der Basisklasse explizit markiert wurde.

Variablen

So können Sie eine Variable nur einmal zuweisen:

Java

public final double pi = 3.14; // essentially a constant

C #

public readonly double pi = 3.14; // essentially a constant

Nebenbei bemerkt unterscheidet sich die Wirkung des readonlySchlüsselworts von der des constSchlüsselworts darin, dass der readonlyAusdruck zur Laufzeit und nicht zur Kompilierungszeit ausgewertet wird , wodurch beliebige Ausdrücke zulässig sind.

Noldorin
quelle
15
Ich möchte hinzufügen, dass alle nicht statischen Methoden in Java standardmäßig virtuell sind. Während Sie in C # das Virtuelle in der ursprünglichen Definition einfach weglassen können, müssen Sie "final" verwenden, um zu vermeiden, dass Unterklassen es in Java überschreiben
Joachim Sauer
166
Gute Antwort - es gibt jedoch noch eine weitere Verwendung von "final" in Java - für eine lokale Variable oder einen Methodenparameter, um eine Neuzuweisung zu verhindern. Es gibt kein direktes c # -Äquivalent dazu.
Serg10
17
readonlyMitgliedsvariablen können in Konstruktoren geändert werden: pastebin.com/AzqzYGiA
rekursiv
8
Beachten Sie auch: Wenn Sie eine Mitgliedsvariable in Java als endgültig deklarieren, beschwert sich der Compiler, wenn nicht jeder Konstruktor in jedem Codepfad einen Wert zuweist, während C # in diesem Szenario nur eine Warnung mit schreibgeschützten Mitgliedsvariablen ausgibt
Mene
1
@NickolayKondratyev: Ja, mein Beispiel war implizit darin enthalten, dass Sie eine Unterklasse aus einer anderen Klasse haben müssen. Sie brauchen die Schnittstelle nicht wirklich; das ist überflüssig, aber sonst sieht das ungefähr richtig aus.
Noldorin
180

Das hängt vom Kontext ab.

LukeH
quelle
1
Tatsächlich ist es nicht erforderlich, dass eine endgültige Variable zugewiesen wird, wenn sie deklariert wird. 'final' bedeutet, dass die Variable durch einen Codepfad zugewiesen werden muss, bevor auf sie verwiesen wird, und kein Codepfad erlaubt, dass die Variable mehr als einmal zugewiesen wird. Dies gilt für Instanzvariablen, was bedeutet, dass Konstruktoren die Variable explizit zuweisen müssen.
Jay
31
+ für For a final local variable or method parameter, there's no direct C# equivalenteine große Unterscheidung.
Daniel B. Chapman
1
Wenn Sie instanziieren , kann const für eine lokale Variable verwendet werden. Es ist nicht gleichwertig, da Sie mit final natürlich separat deklarieren und initialisieren können (und daher unterschiedliche Werte haben), aber nur für den Fall, dass Sie es nicht wussten ...
Griknok
3
constkann nur für Werttypen verwendet werden. Soweit ich weiß, gibt es keine Möglichkeit, eine effektive Konstante für einen lokalen Referenztyp zu erstellen.
Jocull
2
@jocull Mit Strings als einziger Ausnahme.
Raimund Krämer
46

Was hier allen fehlt, ist die Garantie von Java für die endgültige Zuordnung der endgültigen Mitgliedsvariablen.

Für eine Klasse C mit der endgültigen Mitgliedsvariablen V muss jeder mögliche Ausführungspfad durch jeden Konstruktor von C genau einmal V zuweisen. Wenn V nicht oder V nicht zweimal oder mehrmals zugewiesen wird, führt dies zu einem Fehler.

Das schreibgeschützte Schlüsselwort von C # hat keine solche Garantie - der Compiler ist mehr als glücklich, schreibgeschützte Mitglieder nicht zugewiesen zu lassen oder sie innerhalb eines Konstruktors mehrmals zuweisen zu können.

Final und Readonly (zumindest in Bezug auf Mitgliedsvariablen) sind definitiv nicht gleichwertig - final ist viel strenger.

Irgendein Typ
quelle
7

Wie bereits erwähnt, sealedentspricht dies finalMethoden und Klassen.

Im Übrigen ist es kompliziert.

  • Für static finalFelder static readonlyist das nächstmögliche möglich. Sie können das statische Feld in einem statischen Konstruktor initialisieren, der dem statischen Initialisierer in Java ziemlich ähnlich ist. Dies gilt sowohl für Konstanten (Grundelemente und unveränderliche Objekte) als auch für konstante Verweise auf veränderbare Objekte.

    Der constModifikator ist für Konstanten ziemlich ähnlich, aber Sie können sie nicht in einem statischen Konstruktor festlegen.

  • Auf einem Feld, das nicht neu zugewiesen werden sollte, sobald es den Konstruktor verlässt, readonlykann es verwendet werden. Es ist jedoch nicht gleich - finalerfordert genau eine Zuweisung, selbst im Konstruktor oder Initialisierer.
  • Es gibt kein C # -Äquivalent für eine finalmir bekannte lokale Variable. Wenn Sie sich fragen, warum jemand es braucht: Sie können eine Variable vor einem if-else, switch-case oder so deklarieren . Indem Sie es für endgültig erklären, erzwingen Sie, dass es höchstens einmal zugewiesen wird.

    Lokale Java-Variablen müssen im Allgemeinen mindestens einmal zugewiesen werden, bevor sie gelesen werden. Sofern der Zweig nicht vor dem Lesen des Werts herausspringt, wird eine endgültige Variable genau einmal zugewiesen. All dies wird zur Kompilierungszeit überprüft. Dies erfordert gut erzogenen Code mit weniger Spielraum für einen Fehler.

Zusammenfassend hat C # kein direktes Äquivalent von final. Während Java einige nette Funktionen von C # fehlt, ist es für mich als Java-Programmierer erfrischend zu sehen, wo C # kein Äquivalent liefert.

Vlasec
quelle
6

Java-Klasse final und Methode final -> versiegelt. Java-Mitgliedsvariable final -> schreibgeschützt für Laufzeitkonstante, const für Kompilierungszeitkonstante.

Keine Entsprechung für Local Variable final und method argument final

Vijayakumarpl
quelle
0

versiegelt

x2.
quelle
8
Dieser einzige Teil der Antwort, da er vom Kontext abhängt und eine Erklärung und / oder Beispiele hinzufügt, macht ihn für diejenigen, die Hilfe benötigen, viel leichter verdaulich
Rune FS