Bei der Erklärung von Eigenschaften, Methoden und Klassen in Java kann das Schlüsselwort -Finale verwendet werden, um es zu ändern. Die endgültige Variable ist eine Konstante und kann nur einmal zugewiesen werden. Die endgültige Methode kann nicht von einer Unterklasse neu geschrieben werden. Die letzte Klasse kann nicht vererbt werden.
1. Finale Mitglieder
Das Deklarieren eines endgültigen Feldes hilft dem Optimierer, bessere Optimierungsentscheidungen zu treffen. Wenn der Compiler weiß, dass sich der Wert des Feldes nicht ändert, kann er den Wert im Register sicher zwischenspeichern. Das endgültige Feld bietet auch ein zusätzliches Sicherheitsniveau, indem der Compiler das Feld schreibgeschützt ist.
1.1 Über die endgültige Mitgliederzuordnung
1) In Java können gewöhnliche Variablen standardmäßig initialisiert werden. Variablen des endgültigen Typs müssen jedoch explizit initialisiert werden.
2) Die endgültigen Mitglieder können und können nur einmal initialisiert werden.
3) Das endgültige Mitglied muss bei der Deklaration initialisiert werden (wenn er einen Wert direkt an die endgültige Variable zuweist, wenn es definiert ist) oder im Konstruktor und kann an anderer Stelle nicht initialisiert werden.
Beispiel 1 BAT.JAVA
öffentliche Klasse Fledermaus {Final Double Pi = 3,14; // endgültige int i zuweisen, wenn definiert; // Da es im Konstruktor initialisiert werden soll, kann die letzte Liste <Bat> hier nicht zugewiesen werden. // Da es im Konstruktor initialisiert werden soll, kann bat () hier nicht zugewiesen werden {i = 100; list = new LinkedList <bat> (); } Bat (int ii, list <bat> l) {i = ii; list = l; } public static void main (String [] args) {bat b = new Bat (); B.List.Add (New Bat ()); // bi = 25; // B.List = new ArrayList <bat> (); System.out.println ("i =" + bi + "Listentyp:" + b.list.getClass ()); B = neuer Fledermaus (23, New ArrayList <bat> ()); B.List.Add (New Bat ()); System.out.println ("i =" + bi + "Listentyp:" + b.list.getClass ()); }}
Ergebnis:
I = 100 Listentyp: Klasse java.util.linkedListi = 23 Listentyp: Klasse java.util.ArrayList
Es gibt zwei Zeilen von Aussagen in der Hauptmethode, die kommentiert werden. Wenn Sie den Kommentar entfernen, kann das Programm nicht kompilieren. Dies bedeutet, dass unabhängig davon, ob es sich um den Wert von i oder der Art der Liste handelt, nach der Initialisierung nicht geändert werden kann. B kann jedoch den Wert von i oder den Typ der Liste durch Reinitialisierung angeben.
1.2 Ungültige Initialisierung des endgültigen Referenzfeldes
Es ist ein bisschen mühsam, das endgültige Feld richtig zu verwenden, insbesondere für Objektreferenzen, deren Konstruktoren Ausnahmen werfen können. Da das endgültige Feld in jedem Konstruktor nur einmal initialisiert werden muss, kann der Compiler einen Fehler melden, wenn der Konstruktor, auf den das endgültige Objekt verwiesen wird, einen Fehler ausgeben kann, dass das Feld nicht initialisiert wurde. Der Compiler ist im Allgemeinen intelligent genug, um diese Initialisierung in jedem Zweig von zwei Mutex -Code -Zweigen (z. B. wenn ... sonst Blöcke) nur einmal auftritt, aber es ist normalerweise nicht so "verzeihend" zu versuchen ... Fangblöcke zu fangen.
Der folgende Code hat normalerweise Probleme.
Klasse Thingie {public static Thingie getDefaultThingie () {return New Thingie (); }} public class foo {private final Ding Thingie; public foo () {try {Thingie = New Thingie (); } catch (Ausnahme e) {Thingie = Thingie.getDefaultThingie (); // Fehler: Das endgültige Feld Thing wurde möglicherweise bereits zugewiesen}}}
Sie können dies ändern.
öffentliche Klasse Foo {Private Final Thingie; public foo () {Thingie temphingie; Versuchen Sie {temphingie = newyie (); } catch (Ausnahme e) {temphingie = thingie.getDefaultThingie (); } Thingie = temphingie; }}
1.3 über die endgültige Nutzung der Mitglieder
Wenn Sie eine Variable in einer Klasse definieren, fügen Sie das endgültige Schlüsselwort zuvor hinzu, was bedeutet, dass diese Variable nicht geändert werden kann. Die Bedeutung der Unveränderlichkeit ist hier, dass sein Wert für den Grundtyp unveränderlich ist und seine Referenz für die Objektvariable nicht mehr geändert werden kann. Objekte selbst können jedoch geändert werden, und Java bietet keine Möglichkeit, Objekte konstant zu machen. Diese Einschränkung passt auch in Arrays, die Objekte sind.
Beispiel 2
private final int val_one = 9;
Da VAL_ONE und VAL_TOW endgültige primitive Typen mit Kompilierungszeitwerten sind, können beide als Kompilierungszeitkonstanten verwendet werden und es gibt keinen signifikanten Unterschied. Val_Three ist ein typischerer Weg, um Konstanten zu definieren: definiert als öffentlich und kann außerhalb des Pakets verwendet werden. definiert als statisch, um nur eine Kopie hervorzuheben; definiert als endgültig, um anzuzeigen, dass es eine Konstante ist.
Die mit dem endgültige Variablen gekennzeichnete Variable wird zu einer Konstante, aber diese "Konstante" kann nur innerhalb dieser Klasse verwendet werden und kann nicht direkt außerhalb der Klasse verwendet werden. Wenn wir jedoch das öffentliche statische Finale verwenden, um eine Konstante zu markieren, wird diese Konstante zu einer globalen Konstante (ein Feld, das sowohl statisch als auch endgültig ist, nur ein Stück Lagerraum einnimmt, das nicht geändert werden kann). Darüber hinaus können Konstanten, die auf diese Weise definiert sind, nur dann Werte zugewiesen werden, wenn sie definiert sind, und sie können nicht anderswo verwendet werden.
Beispiel 3
Klassenwert {int i; public value (int i) {this.i = i; }} public class FinalData {private static random rand = new random (); private String -ID; public FinalData (String -ID) {this.id = id; } private endgültige int i4 = rand.nextint (20); statische endgültige int i5 = rand.nextint (20); public String toString () {return id + ":" + "i4:" + i4 + ", i5 =" + i5; } public static void main (String [] args) {FinalData fd1 = new FinalData ("fd1"); System.out.println (fd1); System.out.println ("Neue finalData erstellen"); FinalData fd2 = new FinalData ("fd2"); System.out.println (fd1); System.out.println (fd2); }}
Ergebnis
FD1: I4: 6, i5 = 3 Creeating New FinalDatafd1: I4: 6, I5 = 3FD2: I4: 17, i5 = 3
Der Abschnitt Beispiele zeigt den Unterschied zwischen der Definition eines Endwerts als statisch (i5) und nicht statisch (i4). Diese Differenz wird nur angezeigt, wenn der Wert während der Laufzeit initialisiert wird, da der Compiler den kompilierten Wert gleichermaßen behandelt. (Und sie können aus der Optimierung verschwinden.) Sie werden diesen Unterschied sehen, wenn Sie das Programm ausführen. Beachten Sie, dass in FD1 und FD2 der Wert von i5 nicht durch Erstellen eines zweiten FinalData -Objekts geändert werden kann. Dies liegt daran, dass es statisch ist, das beim Laden initialisiert wird, nicht jedes Mal, wenn ein neues Objekt erstellt wird.
Beispiel 4
Klassenwert {int i; public value (int i) {this.i = i; }} öffentliche Klasse… {privater Wert v1 = neuer Wert (11); privater Endwert V2 = neuer Wert (22); privater statischer Endwert V3 = neuer Wert (33); …} Public static void main (String [] args) {… fd1.v2.i ++; // ok-Objekt ist nicht konstant! fd1.v1 = neuer Wert (9); // ok-nicht endgültig fd1.v2 = neuer Wert (0); // Fehler: Referenz kann FD1.v3 = neuer Wert (1) nicht ändern; // Fehler: Referenz nicht ändern…} Variablen von v1 bis v3 veranschaulichen die Bedeutung der endgültigen Referenzen. Wie Sie in Main () sehen können, können Sie nicht glauben, dass Sie seinen Wert nicht ändern können, nur weil V2 endgültig ist. Da es sich um eine Referenz handelt, können Sie V2 nicht wieder auf ein anderes neues Objekt verweisen.
Beispiel 5
öffentliche Klasse… {private final int [] a = {1,2,3,4,5,6}; …} Public static void main (String [] args) {… für (int i = 0; i <fd1.a.length; i ++) fd1.a [i] ++; // ok-Objekt ist nicht konstant! fd1.a = new int [3]; // Fehler: Referenz nicht ändern…} Mit der gleichen Bedeutung für ein Array (es kann seinen Wert ändern, aber es kann nicht auf ein neues Objekt verweisen), ist ein Array eine weitere Referenz.
1.4 Lösen Sie die Einschränkungen der endgültigen Arrays
Obwohl Array -Referenzen endgültig erklärt werden können, können Elemente des Arrays nicht. Dies bedeutet, dass weder die Klassen, die öffentliche Finale Array -Felder enthüllen, noch Verweise auf diese Felder durch ihre Methoden zurückgeben.
// Nicht unveränderlich - Das Status -Array könnte durch eine böswillige // CallerpublicClass gefährlich modifiziert werden. public String [] getStates () {return States; }}
Obwohl eine Objektreferenz als endgültiges Feld deklariert werden kann, kann das Objekt, das es referenziert, immer noch veränderlich sein. Wenn Sie ein invariantes Objekt mit dem endgültigen Feld erstellen möchten, müssen Sie Verweise auf Arrays oder veränderliche Objekte Ihrer Klasse "entkommen" verhindern. Um dies zu tun, ohne das Array wiederholt klonen zu müssen, besteht ein einfacher Weg darin, das Array in eine Liste umzuwandeln.
// unveränderlich - Gibt eine unerpassbare Liste statt, die statt der PublicClass Safestate {private final String [] States = new String [] {"Alabama", "Alaska", "ect"}; private endgültige Liste staatsaSlist = new AbstractList () {öffentliches Objekt get (int n) {return States [n]; } public int size () {return States.length; }}; öffentliche Liste getStates () {return StatesAsList; }}
1.5 über die Verwendung der endgültigen Parameter
Eine weitere Verwendung besteht darin, den Parameter in der Methode als endgültig zu definieren. Für Variablen grundlegender Typen hat dies keine praktische Bedeutung, da Variablen grundlegender Typen Werte übergeben, wenn Sie die Methode aufrufen, dh Sie können die Parametervariable in der Methode ändern, ohne die Aufrufanweisung zu beeinflussen. Für Objektvariablen ist es jedoch sehr praktisch, da Objektvariablen ihre Referenzen beim Bestehen übergeben werden. Auf diese Weise wirkt sich Ihre Änderung von Objektvariablen in der Methode auch die Objektvariablen in der Aufrufanweisung aus. Wenn Sie die Objektvariablen nicht als Parameter in der Methode ändern müssen, hindert Sie ausdrücklich die Deklaration, die aufrufende Methode ungewollt zu ändern und zu beeinflussen.
1.6 Über Parametervariablen in inneren Klassen
Bei Verwendung von Parametervariablen in der Methode in der inneren Klasse muss diese Parametervariable außerdem endgültig deklariert werden, bevor sie verwendet werden kann.
Beispiel 6 inclass.java
öffentliche Klasse inklas {void InnerClass (endgültige String str) {class iclass {icLass () {System.out.println (str); }} ICLASS ic = new icLass (); } public static void main (String [] args) {inclass inc = new inclass (); Inc.innerClass ("Hallo"); }} 2. Schlussmethode
2.1 Abschließende Methode Nutzung
1) Um sicherzustellen, dass das Verhalten einer bestimmten Funktion während des Erbschaftsprozesses unverändert bleibt und nicht überschrieben werden kann, kann die endgültige Methode verwendet werden.
2) Alle privaten und statischen Methoden in der Klasse sind natürlich endgültig.
2.2 endgültige und private Schlüsselwörter
Alle privaten Methoden in der Klasse sind implizit als endgültig festgelegt. Da die private Methode nicht verwendet werden kann, kann sie nicht überschrieben werden.
"Override" wird nur angezeigt, wenn eine Methode Teil der Schnittstelle der Basisklasse ist. Das heißt, ein Objekt muss in der Lage sein, nach oben in seinen primitiven Typ umzuwandeln und dieselbe Methode aufzurufen. Wenn eine Methode privat ist, ist sie nicht Teil der Schnittstelle der Basisklasse. Es ist nur ein Code, der in der Klasse versteckt ist, aber mit demselben Namen. Wenn jedoch in der Exportklasse eine öffentliche, geschützte oder paketende Zugriffsmethode generiert wird, erzeugt die Methode nicht den Fall "nur mit demselben Namen", der in der Basisklasse auftritt. Zu diesem Zeitpunkt haben Sie die Methode nicht außer Kraft gesetzt und gerade eine neue Methode generiert. Da die private Methode nicht berührt werden kann und effektiv versteckt werden kann, muss nichts anderes berücksichtigt werden, außer dass die Organisationsstruktur der Klasse, zu der sie gehört, existieren.
3. Finale Klasse
Wenn eine Klasse als endgültig definiert ist, kann die Klasse nicht vererbt werden. Und weil die endgültige Klasse die Vererbung verbietet, werden alle Methoden in der endgültigen Klasse implizit als endgültig angegeben, weil sie nicht überschrieben werden können.
Das endgültige wird in Klassen oder Methoden verwendet, um zu verhindern, dass die Verknüpfung zwischen den Methoden gebrochen wird. Nehmen wir beispielsweise an, dass die Implementierung einer Methode der Klasse X davon ausgeht, dass die Methode m in irgendeiner Weise funktioniert. Wenn Sie X oder M als endgültig erklären, verhindert die abgeleitete Klasse, M auf diese Weise neu zu definieren, und führt dazu, dass X abnormal funktioniert. Obwohl es möglicherweise besser sein könnte, X ohne diese internen Korrelationen zu implementieren, ist dies nicht immer möglich, und die Verwendung von Final kann zukünftige inkompatible Änderungen verhindern.
PS: Der Unterschied zwischen dem endgültigen, endgültigen und endgültigen Abschluss