2012-07-20 7 views
16
public class Test { 

    private static final String str1 = new String("en"); 
    private static Test instance = initInstance(); 

    private static final String str2 = new String("en"); 
    private static final String str3 = "en"; 

    private Test() { 
    } 

    public static void main(String[] args) { 
    } 

    private static Test initInstance() { 
     instance = new Test(); 
     System.out.println(str1 + ',' + str2 + ',' + str3); 
     return instance; 
    } 
} 

Teoretycznie z statyki wszędzie powinno skutkować "en, pl, en".Java - dziwne zachowanie static String - new String ("xxx") vs "xxx"

Wynik: "en, null, en"

Oczekiwany: "en, null, null" (odkąd odkryto zamówienie statyki rzeczywiście ma znaczenie)

Może ktoś to wyjaśnić? Czym różni się "en" i nowy ciąg ("en")?

+0

+1, ponieważ nie miałem pojęcia, że ​​można zainicjować inline tak ... – Izkata

Odpowiedz

19

Tak. W momencie wywołania metody str2 nie jest jeszcze zainicjowany (pola są inicjowane w kolejności deklaracji), a str3 jest stałą czasu kompilacji.

Stałe czasowe kompilacji są wstawiane przez kompilator w pliku klasy. new String ("..") nie jest stałą, ponieważ używa konstruktora.

Stałe ciągów są definiowane przez literał łańcuchowy: "" i są umieszczane w puli ciągów w instancji jvm, aby mogły być ponownie użyte. W przeciwieństwie do tego, użycie nowego ciągu (..) tworzy nową instancję, więc należy tego unikać.

+5

Czy 'inlined' należy zmienić na' interned'? – corsiKa

11

Dzieje się tak dlatego, że zmienne klasy inicjowane z stałych inicjowane są najpierw, a dopiero potem są bardziej złożone inicjalizatory (jak wyrażeń korzystających new String()) gotowe (te są następnie wykonywane w celu źródłowego). Patrz JLS §8.3.2.1:

8.3.2.1. Inicjalizatory zmiennych klasy

[...]

w czasie wykonywania, static pola, które są final i że są inicjowane z wyrażeniami stałymi (§15.28) są inicjowane pierwszy (§12.4.2). Dotyczy to również takich pól w interfejsach (§9.3.1). Te pola to "stałe", które nigdy nie będą miały domyślnych wartości początkowych (§4.12.5), nawet przez przebiegły program (§13.4.9).

4

1. Jego ponieważ str3 = "en" is a String literal in literal pool, and str1 = new String("en") is a String object w puli obiektów String.

2. Jak „en” jest dosłownym, czyli „stałe” zostanie zainicjowana na początku.

3. Jest nazywany również jako Constant Zwijanie, wstępnego obliczenia stałych do wykonania szybciej.

Powiązane problemy