60

This is a piece of code as an example, after this rest are just methods (look at bottom for maze class). So when this is instantiated, using

Maze labyrinth = new Maze();

and

System.out.println (labyrinth);

This will print out the grid array. Is this legit? I thought all classes needed constructors how does it print out the 2-d grid array?

Maze Class:

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;
    }

}
jahroy
  • 22,322
  • 9
  • 59
  • 108
Aaron
  • 959
  • 2
  • 9
  • 14

7 Answers7

71

It is not required to explicitly define a constructor; however, all classes must have a constructor, and a default empty constructor will be generated if you don't provide any:

public Maze() {
}

See Default Constructor.

mellamokb
  • 56,094
  • 12
  • 110
  • 136
  • How does System.out.println (labyrinth); print out the grid array then? – Aaron Dec 08 '12 at 02:09
  • 3
    Is `toString()` overridden in the actual class with custom print logic (in one of those methods you didn't show us)? I just copied your class into a new Java project, and when I print it out, I get `Maze@50c8d62f` as expected; because custom classes by default don't have a method to print out their contents in a meaningful way. – mellamokb Dec 08 '12 at 02:11
  • 2
    `System.out.println` just calls the `toString()` method of the newly created `Maze` object. – Louis Wasserman Dec 08 '12 at 02:16
  • So any class that has a tostring method and if i try to print out via the reference variable it will automatically call the tostring method? – Aaron Dec 08 '12 at 02:19
  • @LouisWasserman actually println(Object) uses [valueOf](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/io/PrintStream.java#PrintStream.println%28java.lang.Object%29) – fvu Dec 08 '12 at 02:20
  • 1
    @fvu which itself calls `toString` – zapl Dec 08 '12 at 02:22
  • @Aaron: Essentially, yes, as long as it has the proper signature (method name and parameters). It must be exactly called `toString()` with no parameters, otherwise it will not work. – mellamokb Dec 08 '12 at 03:56
15

If you don't write the constructor explicitly, compiler will generate a no-args constructor by default.

public Maze(){

}    

the above will be included If you don't write the constructor explicitly, compiler will generate a no-args constructor by default.

public Maze(){

}    

the above will be included by the compiler.

for Example check the Byte code for this class:

public class ABC {

}

BYTE CODE:

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
}
gukoff
  • 2,112
  • 3
  • 18
  • 30
PermGenError
  • 45,977
  • 8
  • 87
  • 106
  • 2
    @Aaron nothing is advance. its a good practice to check the byte code of your written code. i'd suggest download bytecode outline as a eclipse plugin. :) – PermGenError Dec 08 '12 at 02:27
  • I'm not discreting your knowledge, but I have no idea what those statements mean in the bytecode. Just not at that level yet, I'm still a beginner :). Thanks for your help though, I greatly appreciate it. – Aaron Dec 08 '12 at 02:29
9

To be more accurate, the compiler automatically provides a no-args constructor for a class that doesn't have a constructor, this constructor calls the no-args constructor of the superclass, if the superclass doesn't have a no-args constructor, it's an error, if it does, that's fine.

If your class has no explicit superclass, then it has an implicit superclass (Object), which does have a no-args constructor.

Maroun
  • 94,125
  • 30
  • 188
  • 241
7

The typical answer to this question is "if you don't declare a constructor, a default constructor is created". That is usually true, but not always. It is possible for a class to have no constructor.

(An important distinction to draw here is that the JVM does not require all class files to have a constructor; however, any class defined in Java does have a default constructor if a constructor is not explicitly declared. This answer is presenting an oddity where an example of the former is created from Java code).

Consider the following code, from this question:

public class Outer
{
    private class Inner {}

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

If you compile this with OpenJDK, you will find 3 class files:

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

Outer$1 is the most unusual of these: it has literally nothing in it, not even a constructor:

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

whereas the Inner and Outer classes have the generated constructors:

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
}
Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • Interesting. Do you know why the compiler generated `Outer$1` and if recent compilers still do it? I don't see a reason for the compiler to generate this class from the provided source code. It looks like some sort of marker for the constructor of `Outer$Inner`. – JojOatXGME Jul 15 '20 at 21:34
4

If you don't specify a constructor, a default constructor will be generated by the compiler.

However, any member variable that is not initialized when it's declared will be null.

In other words, if you don't assign a value to grid (like you do in your example) it will be null.

Your example works fine because you happen to assign a value to grid immediately upon declaring it.

jahroy
  • 22,322
  • 9
  • 59
  • 108
0

Java does not actually require an explicit constructor in the class description. If you do not include a constructor, then the Java compiler will create a default constructor with an empty argument.

Pravallika
  • 47
  • 1
  • 10
  • 2
    The same answer has already been given [above](http://stackoverflow.com/a/13773736/650012). No point in adding the same answer again. – Anders Gustafsson May 03 '17 at 08:30
-1

if you mean that you want no one to make an Instance of your class directly i think you can make a constructor set it's access modifier to private and you only can make an instance of this class by a public static method which have access to this private constructor