2012-12-08 25 views
36

To jest kawałek kodu jako przykład, po tym odpoczynku są tylko metody (spójrz na dole dla klasy labiryntu). Więc gdy ten jest tworzony przy użyciuCzy klasa może nie mieć konstruktora?

Maze labyrinth = new Maze(); 

i

System.out.println (labyrinth); 

To wydrukować tablicy siatki. Czy to prawda? Myślałem, że wszystkie klasy potrzebowały konstruktorów, w jaki sposób wypisuje tablicę 2-d grid?

Maze Klasa:

public class Maze 
{ 
    private final int TRIED = 3; 
    private final int PATH = 7; 
    private int[][] grid = { {1,1,1,0,1,1,0,0,0,1,1,1,1}, 
          {1,0,1,1,1,0,1,1,1,1,0,0,1}, 
          {0,0,0,0,1,0,1,0,1,0,1,0,0}, 
          {1,1,1,0,1,1,1,0,1,0,1,1,1}, 
          {1,0,1,0,0,0,0,1,1,1,0,0,1}, 
          {1,0,1,1,1,1,1,1,0,1,1,1,1}, 
          {1,0,0,0,0,0,0,0,0,0,0,0,0}, 
          {1,1,1,1,1,1,1,1,1,1,1,1,1} }; 

    public String toString() 
    { 
     String result = "\n"; 
     for (int row = 0; row < grid.length; row++) 
     { 
      for (int column=0; column < grid[row].length; column++) 
      result += grid[row][column] + ""; 
      result += "\n"; 
     } 
     return result; 
    } 

} 
+2

Kompilator tworzy jeden dla Ciebie. – squiguy

+2

Możesz jeszcze bardziej zagmatwać: http://ideone.com/JN7lGS – zapl

+0

Dla kodu JVM jest to najwyraźniej legalne: http://stackoverflow.com/questions/29478139/is-it-it-valid-to-have-a -jvm-bytecode-class-without-any-constructor –

Odpowiedz

45

Nie jest wymagane, aby wyraźnie zdefiniować konstruktor; Jednak wszystkie klasy musi mieć konstruktor, a konstruktor domyślny pusty zostanie wygenerowany, jeśli nie zapewniają dowolny:

public Maze() { 
} 

Zobacz Default Constructor.

+0

Jak działa System.out.println (labirynt); wydrukować tablicę siatki? – Aaron

+2

Czy 'toString()' nadpisano w rzeczywistej klasie niestandardową logiką drukowania (w jednej z tych metod, które nam nie pokazałeś)? Właśnie skopiowałem twoją klasę do nowego projektu Java, a kiedy go wydrukuję, otrzymuję 'Maze @ 50c8d62f' zgodnie z oczekiwaniami; ponieważ niestandardowe klasy domyślnie nie mają metody drukowania ich treści w znaczący sposób. – mellamokb

+0

Wyślę to tostring() – Aaron

12

Jeśli nie napiszesz bezpośrednio konstruktora, kompilator domyślnie wygeneruje konstruktor no-args.

public Maze(){ 

}  

powyższe zostaną uwzględnione Jeśli nie napiszesz bezpośrednio konstruktora, kompilator domyślnie wygeneruje konstruktor no-args.

public Maze(){ 

}  

powyższe dane zostaną dołączone przez kompilator.

dla przykładu sprawdzić kod binarny dla tej klasy: Kod

public class ABC { 

} 

BYTE:

public class sorting/ABC { 

    // compiled from: ABC.java 

    // access flags 0x1 
    public <init>()V   //Default no-args constructor included by the compiler 
    L0 
    LINENUMBER 7 L0 
    ALOAD 0 
    INVOKESPECIAL java/lang/Object.<init>()V 
    RETURN 
    L1 
    LOCALVARIABLE this Lsorting/ABC; L0 L1 0 
    MAXSTACK = 1 
    MAXLOCALS = 1 
} 
+2

Zbyt zaawansowany dla mnie bro – Aaron

+1

@Aaron nic nie jest z góry. jego dobrą praktyką jest sprawdzenie kodu bajtowego twojego pisemnego kodu. proponuję pobrać kontur kodu bajtowego jako wtyczkę zaćmienia.:) – PermGenError

+0

Nie dyskutuję twojej wiedzy, ale nie mam pojęcia, co te stwierdzenia oznaczają w bajtodzie. Jeszcze nie na tym poziomie, wciąż jestem początkującym :). Dziękuję za pomoc, ale bardzo to doceniam. – Aaron

4

Jeśli nie określić konstruktor, konstruktor domyślny zostanie wygenerowany przez kompilator.

Jednak każda zmienna składowa, która nie została zainicjowana po zadeklarowaniu, będzie pusta.

Innymi słowy, jeśli nie przypiszesz wartości do siatka (tak jak w przykładzie), będzie ona pusta.

Twój przykład działa bez zarzutu, ponieważ przypisujesz wartość do siatkę natychmiast po jej zadeklarowaniu.

4

Aby być bardziej precyzyjne, kompilator automatycznie dostarcza no-args konstruktora dla klasy, która nie posiada konstruktor, konstruktor ten wywołuje No-args konstruktor nadklasie, jeśli nadklasy nie ma konstruktora no-args, to błąd, jeśli tak, to w porządku.

Jeśli klasa nie ma wyraźnych superklasę, to ma ukrytenadklasą (Object), który robi mieć no-args konstruktora.

0

Java nie wymaga jawnego konstruktora w opisie klasy. Jeśli nie dodasz konstruktora, kompilator Java utworzy domyślny konstruktor z pustym argumentem.

+2

Ta sama odpowiedź została już podana [powyżej] (http://stackoverflow.com/a/13773736/650012). Nie ma sensu dodawać tej samej odpowiedzi ponownie. –

0

Typową odpowiedzią na to pytanie jest "jeśli nie zadeklarujesz konstruktora, zostanie utworzony domyślny konstruktor". To jest zwykle prawdziwe, ale nie zawsze . Możliwe jest, że klasa nie ma konstruktora.

(to ważne rozróżnienie zwrócić tutaj jest to, że JVM does not require all class files to have a constructor;. Jednakże każda klasa zdefiniowana w Javadoes have a default constructor if a constructor is not explicitly declared Ta odpowiedź prezentuje osobliwość gdzie przykładem tych pierwszych jest utworzony z kodu Java).

Rozważmy następujący kod z this question:

public class Outer 
{ 
    private class Inner {} 

    void someMethod() 
    { 
     Inner inObj = this.new Inner(); 
    } 
} 

Jeśli skompilować to z OpenJDK, znajdziesz 3 pliki klas:

Outer.class 
Outer$Inner.class 
Outer$1.class 

Outer$1 to najbardziej niezwykły z nich: ma dosłownie nic w nim, nawet konstruktor:

Compiled from "Outer.java" 
class Outer$1 { 
} 

natomiast klas Inner i Outer mieć wygenerowane konstruktorów:

Compiled from "Outer.java" 
class Outer { 
    Outer();  <------------- Generated Constructor 
    Code: 
     0: aload_0 
     1: invokespecial #1     // Method java/lang/Object."<init>":()V 
     4: return 

    void someMethod(); 
    Code: 
     0: new   #2     // class Outer$Inner 
     3: dup 
     4: aload_0 
     5: aconst_null 
     6: invokespecial #3     // Method Outer$Inner."<init>":(LOuter;LOuter$1;)V 
     9: astore_1 
     10: return 
} 
Compiled from "Outer.java" 
class Outer$Inner { 
    final Outer this$0; 

    Outer$Inner(Outer, Outer$1);  <------------- Generated Constructor 
    Code: 
     0: aload_0 
     1: aload_1 
     2: invokespecial #1     // Method "<init>":(LOuter;)V 
     5: return 
} 
Powiązane problemy