2012-12-08 72 views
36

这是一段代码作为一个例子,在这之后其余的只是方法(查看迷宫类的底部)。所以,当这被实例化,使用一个类可以没有构造函数吗?

Maze labyrinth = new Maze(); 

System.out.println (labyrinth); 

这将打印出栅格阵列。 这是合法吗?我认为所有的类都需要构造函数,它如何打印出2维网格数组?

迷宫类别:

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

编译器创建一个给你。 – squiguy

+2

你可以把它变得更加令人困惑:http://ideone.com/JN7lGS – zapl

+0

对于JVM字节它显然是合法的:http://stackoverflow.com/questions/29478139/is-it-valid-to-have-a -jvm-bytecode-class-without-any-constructor –

回答

45

它不需要明确定义构造;然而,所有的类必须有一个构造函数,如果你不提供任何默认的空构造将会产生:

public Maze() { 
} 

Default Constructor

+0

System.out.println(labyrinth);打印出网格数组呢? – Aaron

+2

是否在实际的类中使用自定义打印逻辑覆盖'toString()'(在其中没有给出的方法之一)?我只是将你的课程复制到一个新的Java项目中,当我打印出来时,按预期得到'Maze @ 50c8d62f';因为默认情况下自定义类没有方法以有意义的方式打印出其内容。 – mellamokb

+0

我将发布tostring() – Aaron

12

如果不显式编写构造函数,编译器默认会生成一个无参数构造函数。

public Maze(){ 

}  

将包含上面的内容如果不显式编写构造函数,编译器默认会生成一个无参数构造函数。

public Maze(){ 

}  

以上内容将被编译器包含。

例检查字节码该类:

public class ABC { 

} 

字节码:

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

对我来说太先进了 – Aaron

+1

@Aaron没有任何进展。它是检查你书面代码的字节码的一个好习惯。我建议下载字节码大纲作为一个Eclipse插件。:) – PermGenError

+0

我没有离开你的知识,但我不知道这些语句在字节码中的含义。只是不在那个水平,我仍然是一个初学者:)。感谢您的帮助,但我非常感谢。 – Aaron

4

如果不指定构造函数,默认的构造函数将被生成的编译器。

但是,声明时未初始化的任何成员变量将为空。

换句话说,如果你没有给网格赋值(就像你在你的例子中那样),它将为空。

您的示例工作正常,因为您恰好在声明后立即为网格分配一个值。

4

更准确,编译器自动提供无参数的构造函数一类不具备构造函数,这个构造函数调用无参数的构造函数的,如果超没有no-args构造函数,这是一个错误,如果是这样,那很好。

如果你的类没有明确,然后它有一个隐含的Object),其中确实无参数的构造函数

0

Java实际上并不需要类描述中的显式构造函数。如果不包含构造函数,那么Java编译器将创建一个具有空参数的默认构造函数。

+2

上面已经给出了相同的答案(http://stackoverflow.com/a/13773736/650012)。再次添加相同的答案没有意义。 –

0

典型的这个问题的答案是:“如果你不声明构造函数,默认的构造函数创建”。那是通常是是真的,但不是总是。一个类可能没有构造函数。

(在此提请的一个重要区别是,JVM does not require all class files to have a constructor;然而,在的Javadoes have a default constructor if a constructor is not explicitly declared定义的任何类这个答案正在呈现,其中从Java代码创建前者的例子的怪胎)。

考虑下面的代码,从this question

public class Outer 
{ 
    private class Inner {} 

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

如果编译这个与OpenJDK的,你会发现3类文件:

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

​​3210是最不寻常的这些:它有字面上什么也没有,甚至没有构造:

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

InnerOuter类具有生成构造函数:

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 
} 
相关问题