如何在Java中创建不可变对象? [英] How to create immutable objects in Java?

查看:113
本文介绍了如何在Java中创建不可变对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何用Java创建不可变对象?

How to create immutable objects in Java?

哪些对象应该被称为不可变?

Which objects should be called immutable?

如果我有所有静态成员的类是不可变的吗?

If I have class with all static members is it immutable?

推荐答案

以下是不可变对象的要求。

Below are the hard requirements of an immutable object.


  1. 让班级成为最终

  2. 让所有成员都成为最终成员,明确地将它们设置为
    ,在静态块中,或者在构造函数

  3. 将所有成员设为私有

  4. 否修改状态的方法

  5. 要非常小心限制访问权限可变成员(记住该字段可能是 final 但该对象仍然是可变的。即私有最终日期imStillMutable )。在这些情况下,您应该防御性副本

  1. Make the class final
  2. make all members final, set them explicitly, in a static block, or in the constructor
  3. Make all members private
  4. No Methods that modify state
  5. Be extremely careful to limit access to mutable members(remember the field may be final but the object can still be mutable. ie private final Date imStillMutable). You should make defensive copies in these cases.

制作class final 非常微妙且经常被忽视。如果不是最终的人可以自由扩展你的类,覆盖 public protected 行为,添加可变属性,然后提供他们的子类作为替代。通过声明类 final ,您可以确保不会发生这种情况。

The reasoning behind making the class final is very subtle and often overlooked. If its not final people can freely extend your class, override public or protected behavior, add mutable properties, then supply their subclass as a substitute. By declaring the class final you can ensure this won't happen.

要查看运行中的问题,请考虑以下示例:

To see the problem in action consider the example below:

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 instances
of 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;  
    }

}

在实践中,它很常见在依赖注入环境中遇到上述问题。你没有明确地实例化事物,你给出的超类引用实际上可能是一个子类。

In practice it is very common to encounter the above problem in Dependency Injection environments. You are not explicitly instantiating things and the super class reference you are given may actually be a subclass.

带走是为了对你必须标记的不变性作出硬性保证该类为 final 。这在Joshua Bloch的 Effective Java 中得到了深入介绍,并在< a href =http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html\"rel =noreferrer> Java内存模型。

The take away is that to make hard guarantees about immutability you have to mark the class as final. This is covered in depth in Joshua Bloch's Effective Java and referenced explicitly in the specification for the Java memory model.

这篇关于如何在Java中创建不可变对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆