分配后,使字段的值固定

时间:2015-02-25 11:49:41

标签: java

class A {

    Object obj;

}

我说这个类有字段obj。我想在分配后修改此字段的值。

问题是我不想在构造函数中分配值,因此我无法创建字段final。然后它提出了另一个解决方案:

class A {

    Object obj;

    public void setObj(Object obj) {
        if (obj ==null)
            this.obj = obj;
    }
}

我想知道是否有更好的(更优雅的)。

1 个答案:

答案 0 :(得分:0)

另一种方法是使用函数式编程习惯用法,并通过返回一个新对象来确保你的对象是不可变的。

这个想法是"新对象"不允许你修改字段和"旧对象"正在创建一个新实例(并返回它),而不是简单地设置字段,当被要求时。这保证您的字段仍为final,并且您只能更改一次。

class B {
    private static class ValuedB extends B {
        public ValuedB(Object obj) {
            super(obj);
        }
        @Override
        public Object getObj() {
            return super.obj;
        }
        @Override
        public B setObj(Object obj) {
            return this;
        }
    }
    public B() { 
        this(null);
    }
    private B(Object obj) {
        this.obj = obj;
    }
    private final Object obj;
    public Object getObj() { return null;/* or raise exception */ }
    public B setObj(Object obj) { 
        return new ValuedB(obj);
    }

}

使用myB = b.setObj(...);

进行调用

当然,如果你已经拥有对B实例的多个引用,那么我只需修改一个,所以如果是这样的话 - 这个习惯用法可能不合适。


例如,运行:

public static void main(String[] args) {
    B b = new B();
    System.out.println(b.getObj());
    b = b.setObj("asdf");
    System.out.println(b.getObj());
    b = b.setObj("qwerty");
    System.out.println(b.getObj());
}

将按预期收益:

null
asdf
asdf