2010-11-10 9 views
18

mam ten kod:Jaka jest różnica między nieinicjalizacją a inicjalizacją do wartości NULL?

MyClass object; 

.... some code here where object may or may not be initialised... 

if (object.getId > 0) { 
    .... 
} 

co powoduje błąd kompilacji: object nie mogły zostać zainicjowany, który jest na tyle fair.

Teraz mogę zmienić swój kod do tego:

MyClass object; 

.... some conditional code here where object may or may not be initialised... 

if (object != null && object.getId > 0) { 
    .... 
} 

uzyskać ten sam błąd kompilacji! Mam do zainicjowania object null:

MyClass object = null; 

Więc jaka jest różnica między nie inicjalizacji obiektu i inicjowanie null? Jeśli zadeklaruję obiekt bez inicjalizacji, czy nie jest on pusty?

Dzięki

Odpowiedz

27
  • pola (członków zmienne) są inicjowane null (lub do domyślnej wartości pierwotnej, jeśli są prymitywy)
  • zmienne lokalne nie są inicjalizowane i jesteś odpowiedzialny za ustawienie początkowe wartość.
+0

to jednak moje pytanie: czy "zero" jest wartością? Zawsze uważałem (być może naiwnie) za "brak wartości", a więc równoznaczne z brakiem inicjalizacji. –

+1

Nie wiedziałem o tym. Teraz właśnie nauczyłem się czegoś nowego również dzisiaj :) – Nailuj

+5

@Richard: null jest bardzo zdecydowanie wartością. Jest to wartość, która nie odnosi się do żadnego obiektu. Jest różnica między "nie definitywnie przypisanym" i "zdecydowanie przypisanym, o wartości zerowej". –

3

To jest definicja języka.

Język określa, że ​​zmienne METHOD-scope MUST należy ręcznie zainicjować - jeśli chcesz, aby były uruchamiane jako NULL, musisz to wyraźnie powiedzieć - jeśli tego nie zrobisz, są one zasadniczo w niezdefiniowany stan.

W przeciwieństwie do tego, język stwierdza, że ​​zmienne zakresu CLASS-scope nie muszą być inicjowane ręcznie - brak ich inicjalizacji powoduje, że są automatycznie inicjowane do NULL - więc nie musisz się tym martwić.

Jeśli chodzi o różnicę między dwoma stanami (null vs. undefined), tak, są one zasadniczo takie same - ale język nakazuje, że należy zainicjować zmienną (niezależnie od tego, czy jest to zrobione automatycznie, czy nie, w zależności od w zakresie zmiennej).

+1

Czy to jest -> http: // goo.gl/Dhtebe tylko częściowo prawda? – Sotti

+1

@Sotti, którego odwołanie podasz, dotyczy w szczególności metod o zasięgu KLASY i jest całkowicie poprawne. Ponownie przeczytaj mój wpis, a zauważysz, że rozróżniam zmienne z zakresu METHOD i CLASS. Jak wskazują punkty odniesienia, zmienne o zasięgu klasy są inicjowane z wartościami domyślnymi; jednak zmienne o zasięgu metod nie są. Ponadto należy zapoznać się ze specyfikacją języka Java, zwracając szczególną uwagę na "Zmienna lokalna musi mieć wyraźnie określoną wartość ..." - część. http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.5 – Bane

+1

Świetnie, dla mnie to jasne. Dzięki. – Sotti

0

Twoja deklaracja obiektu jest naprawdę deklaracja wskaźnika lub odniesienia do instancji MojaKlasa na stercie. Jeśli nie zainicjalizujesz wskaźnika, otrzymujesz wskaźnik wskazujący losowo. Poprzez explicity inicjowanie wskaźnika do NULL ustawiasz go tak, aby wskazywał na NULL adres, który kompilator wie, że jest niepoprawny.

Dodatkowe zamieszanie wprowadza się w Javie, ponieważ domyślnie inicjuje zmienne składowe na NULL.

Ma to trochę więcej sensu, jeśli używasz języków niższego poziomu, takich jak C++.

+0

Nie sądzę, że twoje twierdzenie jest poprawne, że niepowodzenie zainicjowania zmiennej java na NULL równa się wskazaniu gdzieś losowego. Rozumiem, do czego zmierzasz, ale nie sądzę, aby było prawidłowe założenie, że możesz zadeklarować zmienną bez jej inicjowania, a tym samym uzyskać dostęp do losowej części pamięci. Rozumiem, że języki niższego poziomu radzą sobie z tym w ten sposób, ale to niekoniecznie oznacza, że ​​Java robi to w ten sam sposób. – Bane

+0

@Bane Nie przyniesie to zbyt wiele, aby przedyskutować, która wartość - jeśli występuje - jest zmienną lokalną przed przypisaniem, ponieważ nie można jej zaobserwować: Kompilator i weryfikator kodu bajtowego nie pozwolą ci uzyskać dostępu do zmiennej lokalnej przed przypisaniem jej. O ile nie wyłączysz weryfikatora kodu bajtowego i nie użyjesz kodu bajtowego do wykonania tego działania. –

+0

To był mój punkt widzenia. ;) – Bane

Powiązane problemy