【问题标题】:Regarding an immutable class关于不可变类
【发布时间】:2012-08-06 22:44:45
【问题描述】:

我有以下查询,我正在研究Java不可变类的概念并提出以下分析..

  • 所有字段都必须是私有的,最好是最终的
  • 确保类不能被覆盖 - 使类成为最终类,或使用静态工厂并保持构造函数私有
  • 必须从构造函数/工厂填充字段
  • 不要为字段提供任何设置器
  • 注意收藏。使用 Collections.unmodifiable*。
  • 另外,集合应该只包含不可变对象
  • 所有 getter 必须提供不可变对象或使用防御性复制
  • 不要提供任何改变对象内部状态的方法。

现在我有以下课程..

public final class Bill {

    private final int amount;
    private final DateTime dateTime;
    private final List<Integers> orders;

}

请告知如何将其制成不可变类。

【问题讨论】:

  • 并非所有这些在技术上都是必需的——例如,String.hashCode() 是延迟计算的,其 hashCode 字段不是最终的,但即使如此,String 仍被认为是不可变的。跨度>
  • > 它的 hashCode 字段不是最终的,这就是为什么提到这些字段最好是最终的。只要由于对对象的外部消息而无法修改它们,成员就可以是非最终的,对吗?

标签: java


【解决方案1】:

你的类是不可变的。现在您可能想要添加一些方法:

public final class Bill {

    private final int amount;
    private final DateTime dateTime;
    private final List<Integers> orders;

    public Bill(int amount, DateTime dateTime, List<Integer> orders) {
        this.amount = amount; //primitive type: ok
        this.dateTime = dateTime; //joda.DateTime is immutable: ok
        this.orders = new ArrayList<Integer> (orders); //make a copy as the caller could modify the list at its end
    }

    // no method that adds or removes from the list

   public List<Integer> getOrders() {
       return Collections.unmodifiableList(orders); //defensive copy
   }
}

或者,您可以在构造函数中使用 this.orders = Collections.unmodifiableList(orders); 并从 getOrders() 中返回它:return orders;,这强制您不应修改该列表,即使在您的类中也是如此。

【讨论】:

    【解决方案2】:

    由于int 是一个原始的并且DataTime(我猜来自JodaTime)是不可变的,你唯一需要做的就是确保你使用不可变列表:

    public final class Bill {
        ...
        public Bill(int amount, DateTime dateTime, List<Integer> orders) {
            this.amount = amount;
            this.dateTime = dateTime;
            this.orders = Collections.unmodifiableList(orders);
        }
        ...
    }
    

    显然,您还需要一个构造函数来初始化final 字段和一些可以访问该字段的方法。

    【讨论】:

      【解决方案3】:

      由于 amount 是一个值类型,datetime 是不可修改的,如果您在其 getter 中返回您的 orders 属性的 Collections.unmodifiable() 版本,则该类将变为不可变。

      【讨论】:

        猜你喜欢
        • 2012-08-13
        • 2010-10-28
        • 1970-01-01
        • 2010-11-20
        • 1970-01-01
        • 2014-10-16
        • 1970-01-01
        • 2011-12-24
        相关资源
        最近更新 更多