Почему можно использовать пустой конструктор? - PullRequest
6 голосов
/ 31 декабря 2008

Я недавно читал немного Java и столкнулся с чем-то новым (идиома?) Для меня: в программе классы с несколькими конструкторами также всегда включают пустой конструктор. Например:

public class Genotype {
  private boolean bits[];
  private int rating;
  private int length;
  private Random random;

  public Genotype() {              //  <= THIS is the bandit, this one right here
    random = new Random();
  }

  /* creates a Random genetoype */
  public Genotype(int length, Random r) {
    random = r;
    this.length = length;
    bits = new boolean[length];

    for(int i=0;i<length;i++) {
        bits[i] =random.nextBoolean();
    }
  }

  /* copy constructor */
  public Genotype(Genotype g,Random r) {
    random = r;
    bits = new boolean[g.length];
    rating = g.rating;
    length = g.length;

    for(int i=0;i<length;i++) {
        bits[i] = g.bits[i];
    }

  }
}

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

Ответы [ 10 ]

9 голосов
/ 31 декабря 2008

Я не уверен, что код, который вы читали, был высокого качества (в прошлом я просматривал некоторый код биоинформатики, и, к сожалению, его часто не пишут профессиональные разработчики). Например, этот третий конструктор не является конструктором копирования, и, как правило, в этом коде есть проблемы, поэтому я бы не стал «читать слишком много в него».

Первый конструктор является конструктором по умолчанию. Он только инициализирует минимум и позволяет пользователям устанавливать остальное с помощью геттеров и сеттеров. Другие конструкторы часто являются «удобными конструкторами», которые помогают создавать объекты с меньшим количеством вызовов. Однако это часто может привести к несоответствиям между конструкторами. Фактически, недавнее исследование показало, что конструктор по умолчанию с последующими вызовами сеттеров предпочтителен.

В некоторых случаях конструктор по умолчанию является критическим. Например, некоторые платформы, такие как digester (используется для создания объектов непосредственно из XML), используют конструкторы по умолчанию. JavaBeans обычно использует конструкторы по умолчанию и т. Д.

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

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

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

5 голосов
/ 31 декабря 2008

Является ли объект Сериализуемым ?

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

Во время десериализации поля несериализуемых классов будут инициализированы с использованием открытого или защищенного конструктора класса без аргументов класса. Конструктор без аргументов должен быть доступен для подкласса, который сериализуем. Поля сериализуемых подклассов будут восстановлены из потока

3 голосов
/ 31 декабря 2008

Да, я согласен, что «пустой» конструктор не всегда должен существовать (по моему опыту новички часто допускают эту ошибку), хотя бывают случаи, когда пустого конструктора будет достаточно. Однако, если пустой конструктор нарушает инвариант, согласно которому все элементы должным образом создаются после построения , пустой конструктор использовать не следует. Если конструктор сложен, лучше разделить конструкцию на несколько защищенных / частных методов. Затем используйте метод static или другой класс Factory , чтобы при необходимости вызывать защищенные методы для построения.

То, что я написал выше, является идеальным сценарием. Однако фреймворки, такие как spring, удаляют логику конструктора из кода и в некоторые файлы конфигурации xml. У вас могут быть функции получения и установки, но, вероятно, их можно избежать из интерфейса, , как описано здесь .

1 голос
/ 31 декабря 2008

Конструктор по умолчанию НЕ обязателен.

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

0 голосов
/ 08 марта 2018

Вы хотите создать пустой конструктор для классов, которые расширили этот класс и так как он был расширен классом ... у ребенка теперь есть супер, который ссылается на класс над ним, это родитель. В случае, если дочерний элемент не определил super (stuff) ... материал внутри, чтобы ссылаться на другие конструкторы, чтобы использовать его, теперь будет пытаться ссылаться на пустой конструктор.

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

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

Это мой первый пост, но я хотел бы понять, насколько я понимаю.

0 голосов
/ 07 октября 2016

Для некоторых классов POJO или простого класса конструктор по умолчанию полезен, когда вы иногда хотите выполнить модульное тестирование с использованием их класса. Вам не нужно имитировать их, вы можете создать новый объект с помощью конструктора по умолчанию и проверить набор значений и получить их или передать в качестве аргумента.

0 голосов
/ 23 июня 2009

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

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

0 голосов
/ 31 декабря 2008

Я обычно пишу один конструктор, который полностью инициализирует объект; если есть другие, они все вызывают это (...) с соответствующими значениями по умолчанию.

Объект должен быть на 100% инициализирован и готов к использованию при его создании.

Некоторые фреймворки, например Hibernate, требуют конструктора без аргументов. То, как они сталкиваются с лучшими практиками, иногда делает меня неловким.

0 голосов
/ 31 декабря 2008

Это НЕ конструктор копирования. В основном вам нужны пустые конструкторы при работе с некоторыми фреймворками. Всегда должен быть пустой конструктор, конечно, публичный или приватный, но, по крайней мере, он позволяет вам контролировать то, как создается (или не) создается класс.

0 голосов
/ 31 декабря 2008

Конструктор по умолчанию не является хорошей практикой для функционального представления. Конструктор по умолчанию используется, если объект имеет глобальную видимость в методе: например, вы хотите записать фактическое состояние объекта в try / catch Вы можете код

MyObejct myObject=null
try{...
}catch(Exception e){
    log.error(myObject);//maybe print null. information?
}

или вы предпочитаете

MyObejct myObject=new Object();
try{...
}catch(Exception e){
log.error(myObject);//sure print  myobject.toString, never null. More information
}

В противном случае создание объекта EMPTY не имеет большого количества логики, но, по моему мнению, создание объекта NULL опасно. Вы можете прочитать этот пост

...