2016-02-11 9 views
5

Hier ist ein Beispielcode (unter der Annahme von Java 8).Ist dieses "s" effektiv endgültig?

while (true){ 
    Socket s = serverSocket.accept(); 
    // some code here ... we don't assign anything to s again here ... 
} 

Ist s effektiv innerhalb der Schleife endgültig?

+0

Ich mache es nicht. Ich frage nach "effective final", vorausgesetzt, ich tue es nicht. –

+2

@ cricket_007: Wenn du das nie machst, dann ist 's' immer noch effektiv endgültig. – Makoto

+0

@ peter.petrov: Es schmerzt mich ein bisschen, aber dieses Duplikat beantwortet Ihre Frage. In Java 8 ist dies gültig; in Java 7 und älter ist dies viel dikuer. – Makoto

Antwort

5

Unter der Annahme, dass s nicht in der Vergangenheit seiner Erklärung zugeordnet ist, dann ja, s ist „effektiv final“, nach den JLS, Section 4.12.4, die es definiert, in Ihrem Fall:

Bestimmte Variablen, die nicht erklärt werden final werden stattdessen als effektiv final:

  • eine lokale Variable, deren declarator einen Initialisierer hat (§14.4.2) ist effektiv endgültige wenn alle folgenden Bedingungen erfüllt sind:

    • Es ist nicht final erklärt.

    • Es tritt nie als die linke Seite in einem Zuweisungsausdruck auf (§15.26). (Beachten Sie, dass die lokale Variable declarator mit dem Initialisierer ist nicht einen Zuweisungsausdruck.)

    • Es tritt nie als Operand eines Präfix oder Postfix Inkrement oder Dekrement-Operator (§15.14, §15.15).

  • Eine lokale Variable, deren declarator einen Initialisierer fehlt, ist effektiv endgültig, wenn alle folgenden Bedingungen erfüllt sind:

    • Es ist nicht endgültig deklariert wird.

    • Wenn es als linke Seite in einem Zuweisungsausdruck auftritt, ist es definitiv nicht zugewiesen und vor der Zuweisung nicht definitiv zugewiesen; das heißt, es ist definitiv nicht zugewiesen und nicht definitiv nach der rechten Seite des Zuweisungsausdrucks zugewiesen (§ 16 (Definite Assignment)).

    • Es tritt nie als der Operand eines Präfix- oder Postfix-Inkrement- oder Dekrementoperators auf.

Sie weisen nur s bei der Deklaration und ist ein Objekt, um es nicht der Operand einer Zunahme oder Abnahme Operator sein kann, so ist es effektiv endgültig.

Darin heißt es auch, dass eine Variable in einem anderen Fall effektiv endgültig sein kann, wenn es nicht belegt ist, wenn es deklariert wird, so lange wird es nur einmal vergeben, es ist auf jeden Fall nicht vor der Deklaration zugewiesen, und es ist auf jeden Fall nach der Erklärung zugewiesen.

Auch am Ende dieses Abschnitts, heißt es:

Wenn eine Variable effektiv final ist, die endgültige Modifikator auf seine Erklärung hinzugefügt wird keine Kompilierung-Fehler nicht vorstellen. Umgekehrt wird eine lokale Variable oder ein lokaler Parameter, der in einem gültigen Programm als final deklariert ist, effektiv endgültig, wenn der Modifikator final entfernt wird.

Sie sollten in der Lage sein, es explizit final zu machen, ohne einen Compilerfehler zu verursachen. Wenn ja, ist es effektiv endgültig.

+0

Hmm. Die beiden Abschnitte, die du zitierst, scheinen in Bezug auf Fälle wie "int i; i = 3; '. Ersteres scheint zu sagen, dass "i" nicht effektiv endgültig ist (da sein Deklarator keinen Initialisierer hat und auf der linken Seite einer Zuweisungsanweisung auftritt), während letzterer das zu sagen scheint 'i' * ist * effektiv endgültig (seit' final int i; i = 3; 'ist absolut gültig). Dient etwas anderes in der Spezifikation diese offensichtliche Diskrepanz? – ruakh

+0

Der Kürze halber hatte ich das Zitat auf die andere Art und Weise gelassen, wie es effektiv sein kann, im Falle einer geteilten Deklaration/Einzelaufgabe. Ich werde es einschließen ... – rgettman

+0

Ah, ich verstehe; Vielen Dank. Ich denke, du hattest Recht, die Kürze zu bevorzugen. Vielleicht lassen Sie den zweiten Punkt einfach als "Eine lokale Variable, deren Deklarator keinen Initialisierer hat, ist effektiv endgültig, wenn [...]" - das heißt, ersetzen Sie alles nach dem Wort "if" mit nur "[...]"? (Oh, und +1 übrigens.) – ruakh