2016-07-27 19 views
15

Napotkałem pytanie z pytaniem: "Które z poniższych stwierdzeń są prawdziwe w przypadku" domyślnego "konstruktora?"Domyślny konstruktor nie inicjuje członków instancji klasy?

i opcja "Inicjuje członków klasy." był nieprawidłowy wybór.

Teraz moje zrozumienie, że jeśli mamy kod, takich jak

Class Test { 
     String name; 
    } 

następnie kompilator tworzy domyślnego konstruktora, który wygląda jak

Class Test { 
     String name; 
     Test(){ 
      super(); 
      name = null; 
     } 
    } 

nie jest domyślny konstruktor inicjowania nazwę użytkownika instancja = null?

+1

Prawdopodobny duplikat [domyślnego konstruktora Javy] (http://stackoverflow.com/questions/4488716/java-default-constructor) –

+2

'class' ma małe litery w Javie. – kamoroso94

Odpowiedz

9

Konstruktor klas nie jest tym, który wykonuje inicjalizację, JVM to robi. Po utworzeniu pamięci dla obiektu, członkowie obiektu są domyślnie inicjowani do pewnej przewidywalnej wartości, która staje się ich wartością domyślną.

Według specification

  • każda zmienna klasy zmiennej przykład lub składnik tablica jest inicjowany na wartość domyślną, gdy jest tworzony (§15.9, §15.10.2)
    • przypadku typu bajt domyślną wartością jest zero, czyli wartość (byte)0.
    • W przypadku typu short domyślną wartością jest zero, czyli wartość (short)0.
    • Dla typu int domyślną wartością jest zero, czyli 0.
    • W przypadku typu long domyślną wartością jest zero, czyli 0L.
    • W przypadku typu float wartość domyślna to zero dodatnie, czyli 0.0f.
    • Dla typu double domyślną wartością jest zero dodatnie, czyli 0.0d.
    • W typie char wartość domyślna to pusty znak, czyli '\u0000'.
    • Dla typu boolean domyślną wartością jest false.
    • Dla wszystkich typów referencji (§4.3) domyślną wartością jest null.

Twoje założenie jest blisko, ale faktem jest, zanim parametry konstruktora są jeszcze oceniony - zanim jeszcze przypisać wartość do każdego z pól - pola te już posiadają swoje wartości domyślne, a robi to JVM.

przeczytać podrozdział §15.9.4 aby zrozumieć, w jaki sposób proces inicjalizacji prowadzone

+0

Czy to oznacza, że ​​dla dobrze napisanych, innych niż domyślne konstruktorów, twoi członkowie są inicjowani, a natychmiast ich wartość zmienia się ponownie? Nie wydaje się bardzo wydajny. –

+0

@LightnessRacesinOrbit Nie zawsze jest tak, że wszystkie domyślne konstruktory zainicjują wszystkich członków. _Well written_ to zabawna właściwość do wypróbowania i oceny. – Gusdor

+0

@LightnessRacesinOrbit: Przyczyniłem się tylko do jednej implementacji Javy, i to było wiele lat temu, ale sposób, w jaki to zrobiliśmy, polegał na przydzieleniu pamięci zerowej (a IIRC - zerowej pamięci po zniszczeniu). Więc tak, w pewnym sensie jest to nieskuteczne w porównaniu z C lub C++, gdzie jest coś takiego jak niezainicjowana pamięć. Za co płacisz, jest to, że nie ma czegoś takiego w Javie. Ale nie jest tak źle, jak jawne przypisanie '0' do elementu danych' byte', który ma zostać nadpisany. To wszystko było typu 'memset', zwykle w wątkach o niskim priorytecie. Nie wiem, czy Oracle robi to w ten sam sposób. –

1

Nie, to nie jest domyślny konstruktor który zainicjować zmiennych instancji dla Ciebie. Każdy typ ma wartość domyślną. W momencie utworzenia obiektu używana jest wartość domyślna.

Jeśli nie zainicjujesz jawnie zmiennych instancji, będą one nadal używać domyślnych wartości zdefiniowanych dla nich niejawnie.

tj 0 dla int, null do typu odniesienia .. itp

Jednak warto zauważyć, że nie należy przyjmować za pewnik, że domyślna wartość jest podana, a nie wybierać do inicjalizacji zmiennych.


Możesz spróbować zdefiniować pusty konstruktor, który przesłania domyślny konstruktor pustą implementacją. Uświadomisz sobie, że wszystkie zmienne instancji nadal będą inicjowane.

3

Czy domyślny konstruktor nie inicjuje elementu członkowskiego instancji name = null?

Nie, konstruktorzy sprawdzony po wszystkie zmienne instancji są inicjowane przez wartości domyślne: 0 lub wartości równoważnej dla primitive numerical types, false dla typu boolean, null dla reference types.

4

W polach Java inicjowane są przed konstruktorem. Można to łatwo świadczy następujący kod:

public class MyClass { 

    int myField = initMyField(); 

    MyClass(){ 
     System.out.println("ctor"); 
    } 

    static int initMyField() { 
     System.out.println("init field"); 
     return 1; 
    } 
} 

wyjście

init field 
ctor 

Można również sprawdzić de skompilowany kod.

+2

-1 to niczego nie dowodzi. Jako niejawne 'super()' można zainicjować inicjalizację na początku konstruktora. –

+0

Rzeczywiście pokazano inną rzecz: Inicjowana inicjalizacja jest faktycznie przenoszona do bloku inicjalizacyjnego klasy, gdzie jest wykonywana po początkowej inicjalizacji 0 wszystkich parametrów (co jest wykonywane przez maszynę JVM po przydzieleniu pamięci dla obiektu) a po wykonaniu tych dwóch, wywoływany jest konstruktor. – Falco

+0

'myField',' initMyField'. Zwróć uwagę na lowerCase. – glglgl

0

Domyślny konstruktor zapewnia domyślne wartości dla obiektów i zwykle jest tworzony przez kompilator, gdy nie jest jawnie zdefiniowany żaden konstruktor. na przykład

class DefaultTest{ 
int id; 
String name; 

void display(){System.out.println(id+" "+name);} 

public static void main(String args[]){ 
DefaultTest s1=new DefaultTest(); 
DefaultTest s2=new DefaultTest(); 
s1.display(); 
s2.display(); 
} 
} 

Uwaga: Ponieważ nie zdefiniowano konstruktor kompilator wygeneruje domyślnego konstruktora, które przypisać wartości null 0 do dwóch obiektów.

-1

Nie, nie inicjalizuje niepoprawnej zmiennej instancji. tylko prymitywna Get zainicjować z domyślnej wartości

tj

Integer nonPrim; 
int prim; 

Następnie po stworzeniu obiektu nonPrim == null; prim == 0

Dzięki

1

Czyni. Chociaż pytanie jest bardziej oparte na użyciu.

public class Main { 
    String x; 

    Main() { 
     x = "Init"; 
    } 

    @Override 
    public String toString() { 
     return x; 

    } 

    public static void main(String[] args) { 
     System.out.println(new Main()); 
    } 

} 

Ouput:

Init 
0

Ilekroć realizujemy klasy Javy, pierwszy Static Flow Control zostanie wykonany.W statycznej Flow Control jeśli tworzymy obiekt następnie zostaną wykonane następujące czynności (w wymienionej kolejności) jako część Inatance Kontrola przepływu:

  1. Identyfikacja członków instancji (zmiennej instancji i instancji bloków) z od góry do dołu.
  2. Wykonywanie przydziałów zmiennych instancji i bloków instancji.
  3. Wykonanie konstruktora.

W powyższym kodzie zmienna instancji "nazwa" jest już przypisana wartości zerowej (domyślna wartość dla typów odniesienia) nawet przed wykonaniem modułu.

Powiązane problemy