如何在Java中创建不可变对象?

如何在Java中创建不可变对象?

哪些对象应称为不可变的?

如果我的所有静态成员都上课,这是不可变的吗?


明月笑刀无情
浏览 560回答 3
3回答

慕的地10843

以下是不可变对象的严格要求。最终上课使所有成员成为最终成员,在静态块或构造函数中显式设置它们将所有成员设为私人否修改状态的方法要特别注意限制对可变成员的访问(请记住,该字段可能final是可变的,但对象仍然可以是可变的。即private final Date imStillMutable)。defensive copies在这种情况下,您应该这样做。上课的final原因很微妙,常常被忽略。如果不是最终的人,他们可以自由地扩展您的类,覆盖public或protected行为,添加可变属性,然后提供其子类作为替代。通过声明该类,final您可以确保不会发生这种情况。要查看实际问题,请考虑以下示例:public class MyApp{    /**     * @param args     */    public static void main(String[] args){        System.out.println("Hello World!");        OhNoMutable mutable = new OhNoMutable(1, 2);        ImSoImmutable immutable = mutable;        /*         * Ahhhh Prints out 3 just like I always wanted         * and I can rely on this super immutable class          * never changing. So its thread safe and perfect         */        System.out.println(immutable.add());        /* Some sneak programmer changes a mutable field on the subclass */        mutable.field3=4;        /*         * Ahhh let me just print my immutable          * reference again because I can trust it          * so much.         *          */        System.out.println(immutable.add());        /* Why is this buggy piece of crap printing 7 and not 3           It couldn't have changed its IMMUTABLE!!!!          */    }}/* This class adheres to all the principles of *  good immutable classes. All the members are private final*  the add() method doesn't modify any state. This class is *  just a thing of beauty. Its only missing one thing*  I didn't declare the class final. Let the chaos ensue*/ public class ImSoImmutable{    private final int field1;    private final int field2;    public ImSoImmutable(int field1, int field2){        this.field1 = field1;        this.field2 = field2;    }    public int add(){        return field1+field2;    }}/*This class is the problem. The problem is the overridden method add(). Because it uses a mutable member it means that I can't  guarantee that all instancesof ImSoImmutable are actually immutable.*/ public class OhNoMutable extends ImSoImmutable{       public int field3 = 0;    public OhNoMutable(int field1, int field2){        super(field1, field2);              }    public int add(){       return super.add()+field3;      }}实际上,在依赖注入环境中遇到上述问题是很常见的。您没有显式实例化事物,并且给出的超类引用实际上可能是子类。要解决的问题是,要坚决保证不变性,您必须将类标记为final。这在Joshua Bloch的Effective Java中进行了深入介绍,并在Java内存模型规范中明确引用。

陪伴而非守候

要使类在Java中不可变,可以注意以下几点: 1.不要提供setter方法来修改该类的任何实例变量的值。2.将课程声明为“最终”。这将防止任何其他类对其进行扩展,从而阻止其覆盖任何可能修改实例变量值的方法。3.将实例变量声明为private和final。4.您还可以将类的构造函数声明为私有,并在需要时添加工厂方法来创建类的实例。这些要点应该有帮助!!
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java