2015-06-07 18 views
7
  1. String str1;
  2. String str2 = null;
  3. String str3 = "";
  4. String str4 = new String();
  5. String str5 = new String("");

Wiem, że dla 3 inicjalizacji powyżej, przedmiotem łańcuch jest zainicjowany w basenie smyczkową a czwarta nie ma nic wspólnego z pulą ciągów.String w Javie

Jaka jest różnica między 1. a 2.? Jeśli jako zmienną wskaźnika przyjmuję str1, to co zapisuje to konkretny adres pamięci, który nigdy nie jest używany przez maszynę JVM lub system operacyjny?

Czy istnieje różnica między 4. a 5.?

Kiedy drukować str1 i str2 bezpośrednio System.out.println(str1) i System.out.println(str2), na str1, nie mogę nawet przejść compilation.For str2, kompilacja jest OK i mogę „null” i wyjście w oknie konsoli. Czemu?

Zmieniano po odpowiedzią @aioobe: więcej pytań:

Chciałbym wiedzieć więcej o „null”. Ponieważ str2 (zmienna referencyjna) jest jak zmienna wskaźnikowa, powinno w niej być coś (bity 0/1) (w pamięci zajmowanej przez tę zmienną wskaźnika). Ponieważ jest on zainicjowany jako null, czy wszystkie-0-bity lub kod bajtowy o wartości zerowej jest zerowe? Innym pytaniem jest to, że jeśli wywołasz metodę toString() na str2 przez str2.toString(), otrzymałem błąd NullPointer w czasie wykonywania. Więc to JVM sprawdza, czy zmienna referencyjna ma wartość zerową? W jaki sposób JVM może wiedzieć, że jest zerowy? JVM sprawdza bity w str2?

Jeszcze jedno pytanie o zerowy w Javie: concatenation of null and a string literal

+0

Zaktualizowałem odpowiedź, edytując ją. – aioobe

+0

Czy każdy, kto zagłosował w dół, podał jakiś powód? Nie mogę tego zrozumieć ... –

+0

Sądzę, że ludzie wierzą, że to było wcześniej zadawane. Część twojego pytania * została * zadana wcześniej, część twojego pytania nie. – aioobe

Odpowiedz

15

Jaka jest różnica pomiędzy 1. i 2.? Jeśli jako zmienną wskaźnika przyjmuję str1, to co zapisuje to konkretny adres pamięci, który nigdy nie jest używany przez maszynę JVM lub system operacyjny?

Jeśli są pola w klasie, nie ma żadnej różnicy, ponieważ wartość domyślna dla pola typu referencyjnego (takich jak String) jest już null.

Jeśli są zmienne lokalne (to zmienne deklarowane w metodzie) str1 nie zostaną zainicjowane niczego, zaś str2 zostanie zainicjowane null. Różnica polega na tym, że zmienna lokalna nie może być użyta, dopóki nie zostanie zainicjalizowana, więc (jak się wydaje odkryłeś) nie możesz wydrukować str1, ale możesz wydrukować str2.

Czy istnieje różnica między 4. a 5.?

Nie, nie semantycznie. Otrzymasz nieco inny kod bajtowy.

Kiedy drukować str1 i STR2 bezpośrednio System.out.println (str1) i System.out.println (STR2), na str1, nie mogę nawet przejść kompilację. Dla str2 kompilacja jest OK i otrzymuję "null" oraz dane wyjściowe w oknie konsoli. Czemu?

To wydaje się wskazywać, że są to zmienne lokalne. Zmienne lokalne należy zainicjować przed ich użyciem.

Chciałbym dowiedzieć się więcej o "zerowej". Ponieważ str2 (zmienna referencyjna) jest jak zmienna wskaźnikowa, powinno w niej być coś (bity 0/1) (w pamięci zajmowanej przez tę zmienną wskaźnika). Ponieważ jest on zainicjowany jako null, czy wszystkie-0-bity lub kod bajtowy z null jest zerowy?

To już został poproszony (a odpowiedział):

Inną kwestią jest to, że jeśli wywołać metodę toString() na str2 przez str2.toString(), Wystąpił błąd NullPointer w czasie wykonywania. Więc to JVM sprawdza, czy zmienną referencyjną jest null?

Tak.

W jaki sposób JVM może wiedzieć, że jest to null? JVM sprawdza bity w str2?

Tak.

+0

To pytanie jest już zbyt duże (i odpowiedź też!). Czy mógłbyś ciąć/wklejać ten ostatni jako nowe pytanie? Obiecuję zrobić wszystko, aby odpowiedzieć ... (Dodaj link do tego tutaj w komentarzach.) – aioobe

1

Każda zmienna w języku Java, która reprezentuje obiekt, nie jest w rzeczywistości wartością, ale wskaźnikiem do (adresu) miejsca w pamięci przechowującego tę zmienną. null to specjalny typ wskaźnika, który oznacza, że ​​zmienna (wskaźnik) jest inicjowana, ale wskazuje na nic. Ponieważ dowolne dwie zmienne łańcuchowe są wskaźnikami, jeśli porównujesz je tak, jak str1 == str2, sprawdzisz, czy zmienne wskazują na to samo wystąpienie. Aby porównać zawartość, wskaźniki wskazują, że musisz użyć równań: str1.equals(str2), ale w tym przypadku musimy być pewni, że str1 nie jest null.