Конструктор по умолчанию-добро или зло? Checkstyle и PMD находятся напротив здесь

Checkstyle говорит:

Class should define a constructor.

PMD говорит:

Avoid unnecessary constructors - the compiler will generate these for you.

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

8 ответов


Мне нравится ответ PMD. Чем меньше кода, тем лучше. Не пишите конструкторы, которые компилятор напишет за вас.

Мне кажется, что основным аргументом для написания конструктора является то, что какой-то плохой программист, который не понимает, как работают конструкторы на Java, может наткнуться на ваш код и запутаться. Мне не нравится писать код, который бессмысленно неясен, но мне также не нравится писать тупой код.


Как и во многих решениях, которые являются "спорными", правда в том, что это действительно не имеет большого значения. Пишите конструктор или нет. Влияние на качество и ремонтопригодность вашего кода будет незначительным. Если вы кодируете с другими, то примите тот же стиль для согласованности, но в противном случае - делайте то, что вам нравится.


когда конструктор по умолчанию является единственным конструктором, он на 100% эквивалентен явно записать его с пустым телом или опустить его. Однако компилятор не будет генерировать конструктор по умолчанию, если у вас есть явно определенные конструкторы, default или нет. Это означает, что если вы полагаетесь на компилятор для создания конструктора, а затем добавляете альтернативные конструкторы, то конструктор по умолчанию исчезает. Лично я бы склонялся к тому, чтобы позволить компилятору сделать генерация в любом случае; если этот конструктор по умолчанию использовался, он будет генерировать предупреждения компиляции и легко добавлять в этот момент. Иначе зачем вообще хранить его?


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

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


Я пойду с Checkstyle. Без явного конструктора (noarg) никто не будет знать, предназначен ли он или нет.

рассмотрим этот класс утилиты:

public class Util {
    // no constructor given - implicit default constructor
    // intended? probably not, but who knows

    public static void foo() {
      // blabla
    }

    public static void bar() {
      // more blabla
    }

}

по умолчанию компилятор генерирует конструктор по умолчанию для вас, поэтому, если вы не хотите указывать какие-либо специальные действия( инициализация членов здесь не имеет значения ), вам не нужно указывать конструктор.

другое дело, что некоторые классы должны иметь согласованное состояние. Например, у вас есть класс Book. Нет смысла создавать книгу без заголовка, поэтому необходимо указать конструктор со строковым параметром:

public Book(String name) {
    this.name = name;
}

как для конструкторы по умолчанию они могут потребоваться, если вы должны сериализовать свой класс или использовать его в маршаллинге/unmarshalling(JAXB требует пустой конструктор по умолчанию).

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

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

также, если ваш класс довольно длинный, вы можете объявить пустой конструктор по умолчанию для повышения читаемости.


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

затем, когда вы добавляете конкретный конструктор, код может больше не компилироваться - или, что еще хуже, код не будет выполняться (может быть отражающей зависимостью от конструктора без параметров - большинство инструментов ORM требуют наличия конструктора по умолчанию для постоянных сущностей).

именно поэтому вы должны явно добавить значение по умолчанию конструктор, если это необходимо.


ИМО Class should define a constructor потому что если вы полагаетесь на конструкторы по умолчанию переменные экземпляра будут иметь значения по умолчанию (ноль для целых чисел, нулем строки и т. д.). Если вы хотите установить переменные экземпляра в некоторое значение по умолчанию всякий раз, когда объект этого класса создается определение конструктора по себе может быть хорошим выбором в этом случае. (При условии, что вы не хотите использовать методы getter & setter)

class Cube {
   private int length;
   private int breadth;
   private int height;

  public Cube() {
      length = 10;
      breadth = 10;
      height = 10;
  }
     ......
     ......
}

теперь, когда вы делаете объект класса Cube1 все экземпляры varibales этого объекта будет составлять 10. Если вы не используете конструктор здесь, переменные экземпляра (длина, ширина и высота) будут иметь значения по умолчанию (ноль в этом случае).


отредактировано : [добавлено еще одно]

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

помните : компилятор делает конструктор по умолчанию для вашего класса, только если этот класс не содержит никаких других конструкторов.