Ich überprüfe den Sun Certification Study Guide und es gibt eine Passage, die den endgültigen Modifikator beschreibt. Es sagt
"Wenn Programmierer die Zivilisation der String-Klasse erweitern könnten, wie wir wissen, könnte sie zusammenbrechen"
Was meint er? Wenn es möglich wäre, String Class zu erweitern ... würde ich einfach keine Klasse namens MyString haben, die alle Strings Eigenschaften erbt. Wie wäre es möglich, die tatsächliche String-Klasse in irgendeiner Weise zu ändern, indem Sie sie nur erweitern?
Vielen Dank für Ihre Antworten
Nun, ein Problem besteht darin, dass Sie die Sicherheit des jvm höchstwahrscheinlich auf unzählige Arten unterwandern können, wenn Sie die String-Klasse ableiten können. Viele der Berechtigungen überprüfen verschiedene String-Werte, um festzustellen, ob eine bestimmte Aktion zulässig ist. Wenn Ihr Code die Zeichenfolgenwerte liefert, können Sie eine String-Instanz zurückgeben, die "auscheckt", wenn der Sicherheitsmanager sie anschaut, aber später wie ein völlig anderer Wert wirkt.
Beispiel: Sie haben eine sensible jvm-weite Konfiguration:
%Vor% Jetzt implementiere ich einen benutzerdefinierten String, der die Methode startsWith()
überschreibt, um false
zurückzugeben, wenn der Wert "com.sun."
übergeben wurde, aber der tatsächliche Wert meiner Zeichenfolge beginnt mit com.sun.
.
Ganz zu schweigen von der allgemeinen Erwartung, dass Strings unveränderlich sind, was, wenn sie kaputt gehen würde, alle Arten von allgemeinem Chaos verursachen könnte (wie in anderen Antworten ausführlicher erwähnt).
Das Erweitern einer Klasse hat keinen Einfluss auf die Basisklasse. Es kann sich jedoch auf die Consumers der Basisklasse auswirken.
Wenn Sie sagen, dass Sie in der Lage wären, String
zu erweitern, könnten Sie beispielsweise Folgendes schreiben:
Nun übergeben Sie diese Klasse an alles, was eine Zeichenfolge verwendet, und es besteht die Möglichkeit, dass Sie das Programm schnell beenden würden. Nicht das Ende der Zivilisation, aber es gibt etwas unheilvollere Dinge, die Sie tun könnten.
Berücksichtigen Sie, dass in der Java-API Konstrukte wie:
angezeigt werden %Vor% die Strings für die Indizierung verwenden. Eine sehr übliche Sache, z.B. für Immobilien und - und das ist wahrscheinlich am schlechtesten in sicherheitsrelevanten Orten . Dieser Code basiert auf einem nicht modifizierten String
, um sicher zu bleiben.
Aber jetzt lassen Sie Ihre modifizierte String
-Klasse z. Umkehr der Strings an Ort und Stelle.
Dann würde die Welt, wie wir sie kennen, zusammenbrechen, weil überall Karten zu einem verrückten Chaos werden würden. Die Protokollierung würde fehlschlagen usw.
Viel Code hängt davon ab, dass die String
-Klasse unveränderlich ist und, wenn sie wirklich unveränderlich ist, welche Funktionalität könnten Sie ihr trotzdem hinzufügen?
Das Erweitern einer Klasse wirkt sich nicht auf die Klasse aus. Da es sich bei jeder geerbten Klasse jedoch auch um eine Basisklasse handelt, sollte sie sich an die Verhaltensregeln der Basisklasse halten. Wenn Programmierer gängige Framework-Typen ändern sollten, konnte man sich nicht darauf verlassen, dass diese Klassen wie erwartet funktionieren. Sie möchten also verhindern, dass solche Klassen missbraucht werden - dies geschieht mit dem final Schlüsselwort
Die Übertreibung der Katastrophe ist wahrscheinlich eine Anspielung auf Sicherheitsaspekte der Veränderlichkeit von String (im). Eine Zeichenfolge wird oft als Parameter an verschiedene E / A-Ressourcenverbindungs-APIs (z. B. JDBC und Datei-E / A) übergeben. Solch eine Zeichenfolge, wenn oft entweder eine Verkettung von Ressourcen-Locators und Authentifizierungs-Credentials und diese API eine Überprüfung durchführen, um sicherzustellen, dass die Credentials für die angeforderte Ressource gültig sind, bevor die Verbindung zurückgegeben wird. Wenn String änderbar wäre, würde dies ein Gateway für alle Arten von Sicherheitsverletzungen öffnen als Ressourcenzeiger / -adresse (wie zum Beispiel ein Datenbankname für eine DB-Verbindung oder ein Dateiname mit vertraulichen Informationen für einen Benutzer) em> kann geändert werden, nachdem die Authentifizierung erfolgreich war, aber bevor die Ressourcenverbindung für die angeforderte Originalressource hergestellt wird , was zu einem nicht autorisierten Zugriff und einer Untersteuerung der Zugriffssteuerung führt.
Ein weiterer Grund dafür, String unveränderlich zu machen, besteht darin, es threadsicher zu machen.
Eigentlich hat das Problem nichts damit zu tun, einfach String
oder irgendeine andere Klasse zu erweitern.
Das Problem liegt tatsächlich bei Java selbst. Das Problem ist, dass Sie den Vertrag, den ein bestimmtes Objekt implementiert, in seinem Code nicht wirklich definieren können. Es wird im Code für String
nicht wirklich angegeben, dass es unveränderlich ist, da die Unveränderlichkeit nicht spezifiziert werden kann, sondern nur codiert werden kann. Dieser Vertrag ergibt sich nur aus der tatsächlichen Umsetzung von String
.
Wenn es möglich wäre, in der Java-Sprache anzugeben , dass String
und Number
und Integer
usw. unveränderlich sind, müssten wir diese Klassen nicht final
machen. Meiner Meinung nach ist dies eine schwächende Krankheit von Java, dass Sie den Vertrag nicht im Code definieren können. Sie können es nur codieren und dokumentieren.
Ich würde gerne in der Lage sein, string zu erweitern und vielleicht ein UppercaseString extends String
zu definieren, aber es gibt kein contract(immutable,interned)
Schlüsselwort in Java, deshalb kann ich das nicht tun, weil das einzige verfügbare Schlüsselwort diesem Vertrag am nächsten kommt final
anstelle von immutable
wie es sein sollte.
Tags und Links java inheritance final