Я недавно начал читать «Эффективную Java» Джошуа Блоха. Я нашел идею паттерна «Строитель» [пункт 2 в книге] действительно интересной. Я пытался реализовать это в своем проекте, но были ошибки компиляции. Вот, по сути, то, что я пытался сделать:
Класс с несколькими атрибутами и его класс строителя:
public class NutritionalFacts {
private int sodium;
private int fat;
private int carbo;
public class Builder {
private int sodium;
private int fat;
private int carbo;
public Builder(int s) {
this.sodium = s;
}
public Builder fat(int f) {
this.fat = f;
return this;
}
public Builder carbo(int c) {
this.carbo = c;
return this;
}
public NutritionalFacts build() {
return new NutritionalFacts(this);
}
}
private NutritionalFacts(Builder b) {
this.sodium = b.sodium;
this.fat = b.fat;
this.carbo = b.carbo;
}
}
Класс, в котором я пытаюсь использовать вышеуказанный класс:
public class Main {
public static void main(String args[]) {
NutritionalFacts n =
new NutritionalFacts.Builder(10).carbo(23).fat(1).build();
}
}
Я получаю следующую ошибку компилятора:
включающий экземпляр, который содержитffectivejava.BuilderPattern.NutritionalFacts.Builder требуется NutritionalFacts n = new NutritionalFacts.Builder (10) .carbo (23) .fat (1) .build ();
Я не понимаю, что означает сообщение. Пожалуйста, объясни. Приведенный выше код похож на пример, предложенный Блохом в его книге.
java
design-patterns
builder-pattern
Сваранга Сарма
источник
источник
Ответы:
Сделайте строителя
static
классом. Тогда это будет работать. Если он не является статичным, ему потребуется экземпляр своего класса-владельца - и дело не в том, чтобы иметь его экземпляр, и даже в том, чтобы запретить создание экземпляров без компоновщика.Ссылка: вложенные классы
источник
Builder
естьstatic
в примере в книге (стр. 14, строка 10 во 2-м издании).Вы должны сделать класс Builder статическим, а также сделать поля окончательными и иметь методы получения, чтобы получить эти значения. Не предоставляйте установщики для этих значений. Таким образом, ваш класс будет совершенно неизменным.
И теперь вы можете установить свойства следующим образом:
источник
final
поля имеют смысл, только если поля всегда нужны во время инициализации. Если нет, то поля не должны бытьfinal
.Вы пытаетесь получить доступ к нестатическому классу статическим способом. Перейдите
Builder
наstatic class Builder
и это должно работать.Пример использования, который вы приводите, терпит неудачу, потому что нет экземпляра
Builder
настоящего. Статический класс для всех практических целей всегда создается. Если вы не сделаете это статичным, вам нужно будет сказать:Потому что вам нужно будет
Builder
каждый раз строить новое .источник
Чтобы создать внутренний конструктор в Intellij IDEA, проверьте этот плагин: https://github.com/analytical/innerbuilder
источник
Вам нужно объявить
Builder
внутренний класс какstatic
.Консультируйтесь с некоторой документацией как для нестатических внутренних классов, так и для статических внутренних классов .
По сути, нестатические экземпляры внутренних классов не могут существовать без присоединенного экземпляра внешнего класса.
источник
Если у вас есть идея, на практике вы можете найти Ломбок
@Builder
гораздо более удобным.@Builder
позволяет вам автоматически создавать код, необходимый для того, чтобы ваш класс мог быть создан с помощью такого кода, как:Официальная документация: https://www.projectlombok.org/features/Builder
источник
Это означает, что вы не можете создать вложенный тип. Это означает, что сначала вы должны создать экземпляр «родительского» класса, а затем из этого экземпляра вы можете создавать вложенные экземпляры классов.
Вложенные классы
источник
Класс Builder должен быть статическим. Сейчас у меня нет времени, чтобы на самом деле протестировать код, кроме этого, но если он не работает, дайте мне знать, и я еще раз посмотрю.
источник
Я лично предпочитаю использовать другой подход, когда у вас есть 2 разных класса. Так что вам не нужен статический класс. Это в основном, чтобы избежать записи,
Class.Builder
когда вам нужно создать новый экземпляр.Итак, вы можете использовать свой конструктор так:
источник
Как многие уже заявили здесь, вам нужно сделать класс
static
. Небольшое дополнение - если хотите, есть другой путь без статического.Учти это. Реализация компоновщика путем объявления чего-то наподобие
withProperty(value)
установщиков типов внутри класса и заставить их возвращать ссылку на себя. При таком подходе у вас есть один элегантный класс, который является потокобезопасным и лаконичным.Учти это:
Проверьте это для большего количества примеров Java Builder .
источник
Вам нужно изменить класс Builder на статический класс Builder . Тогда все будет работать нормально.
источник