2012-12-08 16 views
36

Dies ist ein Stück Code als Beispiel, nach diesem Rest sind nur Methoden (siehe unten für Labyrinth-Klasse). Wenn also wird diese instanziiert, mitKann eine Klasse keinen Konstruktor haben?

Maze labyrinth = new Maze(); 

und

System.out.println (labyrinth); 

Dies wird aus dem Grid-Array drucken. Ist das legitim? Ich dachte, alle Klassen benötigten Konstruktoren, wie wird das 2-d-Grid-Array ausgegeben?

Maze Klasse:

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

Der Compiler für Sie erstellt. – squiguy

+2

Sie können es noch verwirrender machen: http://ideone.com/JN7lGS – zapl

+0

Für JVM Bytecode ist es scheinbar legal: http://stackoverflow.com/questions/29478139/is-it-valid-to-have-a -jvm-Bytecode-Klasse-ohne-beliebigen-Konstruktor –

Antwort

45

ist es nicht erforderlich explizit einen Konstruktor definieren; jedoch müssen alle Klassen einen Konstruktor haben, und ein Standard leeren Konstruktor wird erzeugt, wenn Sie nicht zur Verfügung gestellt:

public Maze() { 
} 

Siehe Default Constructor.

+0

Wie funktioniert System.out.println (labyrinth); das Grid-Array dann ausdrucken? – Aaron

+2

Wird 'toString()' in der tatsächlichen Klasse mit benutzerdefinierter Drucklogik überschrieben (in einer der Methoden, die Sie uns nicht gezeigt haben)? Ich habe Ihre Klasse einfach in ein neues Java-Projekt kopiert, und wenn ich es ausgedruckt habe, bekomme ich 'Maze @ 50c8d62f' wie erwartet; weil benutzerdefinierte Klassen standardmäßig keine Methode haben, um ihre Inhalte sinnvoll auszudrucken. – mellamokb

+0

Ich poste den tostring() – Aaron

12

Wenn Sie den Konstruktor nicht explizit schreiben, generiert der Compiler standardmäßig einen No-Args-Konstruktor.

public Maze(){ 

}  

die oben wird aufgenommen werden, wenn Sie den Konstruktor nicht explizit schreiben, Compiler generiert einen No-args Konstruktor standardmäßig.

public Maze(){ 

}  

Das obige wird vom Compiler eingeschlossen.

für Beispiel die Byte-Code für diese Klasse überprüfen:

public class ABC { 

} 

Bytecode:

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

Zu fortgeschritten für mich bro – Aaron

+1

@Aaron nichts ist Fortschritt. Es ist eine gute Übung, den Byte-Code Ihres geschriebenen Codes zu überprüfen. Ich würde vorschlagen, Bytecode-Gliederung als Eclipse-Plugin herunterzuladen.:) – PermGenError

+0

Ich bin nicht diskret Ihr Wissen, aber ich habe keine Ahnung, was diese Aussagen im Bytecode bedeuten. Nur noch nicht auf diesem Niveau, ich bin noch ein Anfänger :). Vielen Dank für Ihre Hilfe, ich schätze es sehr. – Aaron

4

Wenn Sie durch die nicht einen Konstruktor angeben, wird ein Default-Konstruktor erzeugt werden Compiler.

Jede Membervariable, die bei der Deklaration nicht initialisiert wird, ist jedoch null.

Mit anderen Worten, wenn Sie Grid (wie Sie in Ihrem Beispiel tun) keinen Wert zuweisen, wird es null sein.

Ihr Beispiel funktioniert gut, weil Sie Grid sofort nach der Deklaration einen Wert zuweisen.

4

genauer zu sein, der Compiler liefert automatisch ein no-args Konstruktor für eine Klasse, die keinen Konstruktor hat, dieser Konstruktor ruft die no-args Konstruktor der Super, wenn der übergeordneten Klasse hat keinen no-args Konstruktor, es ist ein Fehler, wenn es das tut, ist das in Ordnung.

Wenn Ihre Klasse keine expliziten Super hat, dann hat es eine impliziteSuper (Object), die tut haben eine no-args Konstruktor.

0

Java benötigt keinen expliziten Konstruktor in der Klassenbeschreibung. Wenn Sie keinen Konstruktor einschließen, erstellt der Java-Compiler einen Standardkonstruktor mit einem leeren Argument.

+2

Die gleiche Antwort wurde bereits [oben] (http://stackoverflow.com/a/13773736/650012) gegeben. Kein Grund, dieselbe Antwort noch einmal hinzuzufügen. –

0

Die typische Antwort auf diese Frage lautet "Wenn Sie keinen Konstruktor deklarieren, wird ein Standardkonstruktor erstellt". Das ist normalerweise wahr, aber nicht immer. Es ist möglich, dass eine Klasse keinen Konstruktor hat.

(Ein wichtiger Unterschied hier zu ziehen ist, dass die JVM does not require all class files to have a constructor;. Jedoch jede Klasse definiert in Javadoes have a default constructor if a constructor is not explicitly declared Diese Antwort eine Kuriosität präsentiert, wo ein Beispiel für ersteres von Java-Code erstellt wird).

Betrachten Sie den folgenden Code, von this question:

public class Outer 
{ 
    private class Inner {} 

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

Wenn Sie dies mit OpenJDK kompilieren, werden Sie 3 Klassendateien finden:

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

Outer$1 das ungewöhnlichste davon ist: es hat buchstäblich nichts darin, nicht einmal ein Konstruktor:

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

, während die Inner und Outer Klassen haben die generierten Konstrukteure:

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 
} 
Verwandte Themen