【问题标题】:How can we create immutable class object using setter instead constructor.As I want to use its setter method .Does it Possible to make immutable?我们如何使用 setter 而不是构造函数创建不可变的类对象。因为我想使用它的 setter 方法。是否有可能使不可变?
【发布时间】:2017-11-10 12:25:43
【问题描述】:

使用外部类的 setter 方法创建不可变类。因为我有一个 POJO 类对象创建可以使用 setter 方法完成。如何使用 setter 使不可变类成为可能

【问题讨论】:

  • 如果它有一个setter,它就不是不可变的。您不使用 setter 创建;这就是构造函数的用途。这个问题没有意义。
  • 是的,你似乎把它弄反了。如果可以在创建对象后设置对象的某些方面,则它不是不可变的。
  • 假设我想在构造函数调用之后实例化不可变和可变属性,这将是第一次。在初始化期间设置不可变对象属性是否有任何限制?作为一个 POJO 类,我想使用 setter。如果是这样的话。这个问题在 AT&T 采访中被问到..

标签: java core


【解决方案1】:

Setter 是变异器。 https://en.wikipedia.org/wiki/Mutator_method

我认为您可能指的是工厂方法? https://www.tutorialspoint.com/design_pattern/factory_pattern.htm

或者也许你正在做一些混合的事情。

比我更有经验的人会有更好的答案。

【讨论】:

  • 我知道二传手是变异者。事实上脂肪模式不是问题的答案。
【解决方案2】:

您可以使用构建器模式。在那里,您有一个单独的构建器类,每个字段都有一种设置器。最终的build() 最终创建了不可变对象。

public final class Person {

  private final String forename;
  private final String surename;
  private final int age;
  
  private Person(String forename, String surename, int age) {
    this.forename = forename;
    this.surename = surename;
    this.age = age;
  }

  public String getForename() {
    return forename;
  }

  public String getSurename() {
    return surename;
  }

  public int getAge() {
    return age;
  }
  
  public static PersonBuilder createBuilder() {
    return new PersonBuilder();
  }

  public static class PersonBuilder {
    
    private String forename;
    private String surename;
    private int age;
    
    private PersonBuilder() {
      
    }
    
    public PersonBuilder withForename(String forename) {
      this.forename = forename;
      return this;
    }
    
    public PersonBuilder withSurename(String surename) {
      this.surename = surename;
      return this;
    }
    
    public PersonBuilder withAge(int age) {
      this.age = age;
      return this;
    }
    
    public Person build() {
      return new Person(forename, surename, age);
    }
  }
  

然后您可以像这样创建Person 实例:

Person person = Person.createBuilder().withSurename("Krueger")
                        .withForename("Freddy").withAge(47).build();

有了建筑商,您就可以两全其美。设置器(包括流式 API)和不可变对象的灵活性。

编辑:

Joshua Bloch 在他的《Effective Java》一书中第 15 条:“最小化可变性”中陈述:

要使类不可变,请遵循以下五个规则:

  1. 不要提供任何修改对象状态的方法(称为 mutators)。

  2. 确保类不能扩展。 [...]

  3. 将所有字段设为最终字段。 [...]

  4. 将所有字段设为私有。 [...]

  5. 确保对任何可变组件的独占访问。 [...]

为了实现第 2 点,我在上面的 Person 类中添加了 final 关键字。

根据这个被广泛接受的不变性定义,具有 setter 的类本身不是不可变的,因为它违反了第 1 点。

如果认为在面试中问这个问题的目的是看候选人是否能够认识到问题本身的差异,以及关于不变性的知识以及创建不可变类实例的各种替代方案的程度(每构造函数,每个静态工厂方法,每个工厂类,每个构建器模式,...)。

【讨论】:

  • 这可以保持不变性行为但是我需要间接使用不可变类的setter来创建对象。
  • @nityananda:编辑了我的答案,希望能更清楚地了解您的原始问题。
猜你喜欢
  • 2019-12-25
  • 1970-01-01
  • 2019-10-25
  • 2015-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多