Может ли класс не иметь конструктора?

Это кусок кода в качестве примера, после этого все остальные методы (посмотрите на класс лабиринта внизу). Поэтому, когда это создается, используя

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

}

6 ответов

Решение

Не требуется явно определять конструктор; однако все классы должны иметь конструктор, и пустой конструктор по умолчанию будет сгенерирован, если вы его не предоставите:

public Maze() {
}

Смотрите конструктор по умолчанию.

Если вы не напишите конструктор явно, компилятор по умолчанию сгенерирует конструктор без аргументов.

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
}

Чтобы быть более точным, компилятор автоматически предоставляет конструктор без аргументов для класса, у которого нет конструктора, этот конструктор вызывает конструктор без аргументов суперкласса, если суперкласс не имеет конструктора без аргументов, Это ошибка, если это так, это нормально.

Если у вашего класса нет явного суперкласса, то у него есть неявный суперкласс (Object), который имеет конструктор без аргументов.

Типичный ответ на этот вопрос "если вы не объявляете конструктор, создается конструктор по умолчанию". Это обычно так, но не всегда. Для класса возможно не иметь конструктора.

(Важное различие, которое следует здесь провести, заключается в том, что JVM не требует, чтобы все файлы классов имели конструктор; однако любой класс, определенный в Java , имеет конструктор по умолчанию, если конструктор не объявлен явно. Этот ответ представляет странность, когда Пример первого создан из кода Java).

Рассмотрим следующий код из этого вопроса:

public class Outer
{
    private class Inner {}

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

Если вы скомпилируете это с OpenJDK, вы найдете 3 файла классов:

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

Outer$1 это самый необычный из них: в нем буквально ничего нет, даже конструктор:

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

тогда как Inner а также Outer классы имеют сгенерированные конструкторы:

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
}

Если вы не укажете конструктор, компилятор сгенерирует конструктор по умолчанию.

Однако любая переменная-член, которая не инициализируется при объявлении, будет иметь значение null.

Другими словами, если вы не назначите значение для сетки (как вы делаете в своем примере), оно будет нулевым.

Ваш пример работает нормально, потому что вы случайно присваиваете значение grid сразу после его объявления.

Java на самом деле не требует явного конструктора в описании класса. Если вы не включите конструктор, то компилятор Java создаст конструктор по умолчанию с пустым аргументом.

Если вы имеете в виду, что вы не хотите, чтобы никто не создавал экземпляр вашего класса напрямую, я думаю, вы можете заставить конструктор установить его модификатор доступа как частный, и вы можете создать экземпляр этого класса только с помощью общедоступного статического метода, который имеет доступ к этому частному конструктор

Другие вопросы по тегам