Почему можно также использовать пустой конструктор?

StackOverflow https://stackoverflow.com/questions/402514

  •  03-07-2019
  •  | 
  •  

Вопрос

Недавно я читал 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];
    }

  }
}

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

Это было полезно?

Решение

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

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

Есть также определенные случаи, когда конструктор по умолчанию имеет решающее значение.Например, некоторые платформы, такие как дайджест (используемые для создания объектов непосредственно из XML), используют конструкторы по умолчанию.JavaBeans обычно используют конструкторы по умолчанию и т.д.

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

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

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

Другие советы

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

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

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

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

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

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

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

Конструктор по умолчанию не является хорошей практикой для функционального представления.Конструктор по умолчанию используется, если объект имеет глобальную видимость метода:Например, вы хотите зарегистрировать фактическое состояние объекта в 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, на мой взгляд, вредно.Ты можешь читать эта почта

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

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

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top