Oracle Java官网关于不可变对象的解析

41 篇文章 0 订阅
5 篇文章 0 订阅

一、Immutable Objects(不可变对象)

1. 原文链接

2. 原文翻译

An object is considered immutable if its state cannot change after it is constructed.
如果一个对象的状态在被构建后不会再变,则被认为是不可变的。
(结合下文,如果一个对象被创建后,其状态固定不会再被更改,如果想得到该对象的另外一个状态,则是通过新创建另一个对象(赋值不同)的方式)
Maximum reliance on immutable objects is widely accepted as a sound strategy for creating simple, reliable code.
对不可变对象的最大依赖被广泛认为是创建简单、可靠代码的一种良好策略。。
Immutable objects are particularly useful in concurrent applications. Since they cannot change state,
不可变对象在并发应用程序中特别有用。由于它们不能改变状态,
they cannot be corrupted by thread interference or observed in an inconsistent state.
因此它们不能被线程干扰破坏或观察到处于不一致的状态。
Programmers are often reluctant to employ immutable objects, because they worry about the cost of creating a new object as opposed to updating an object in place.
程序员通常不愿意使用不可变对象,因为他们担心创建新对象的成本,而不是在适当的地方更新对象。
(即:宁愿更新现有对象,而都不去创建新对象,都认为创建新对象的成本大于更新对象的成本,但更新已有对象的成本在于其破坏了该对象【共享资源】在多个线程间的一致性,为了维护其一致性,需要额外的同步处理,比如加锁)
The impact of object creation is often overestimated, and can be offset by some of the efficiencies associated with immutable objects.
创建对象的影响经常被高估,并且可以被一些与不可变对象相关的效率所抵消.
(即:【创建对象所造成的成本】 可以被【不可变对象本身所带来的效率收益】所抵消抹平的)
These include decreased overhead due to garbage collection, and the elimination of code needed to protect mutable objects from corruption.
这包括减少垃圾收集带来的开销,以及消除保护可变对象免受破坏所需的代码。

二、A Synchronized Class Example(一个同步类的例子)

1. 原文链接

2.原文代码

public class SynchronizedRGB {

    // Values must be between 0 and 255.
    private int red;
    private int green;
    private int blue;
    private String name;

    private void check(int red,
                       int green,
                       int blue) {
        if (red < 0 || red > 255
            || green < 0 || green > 255
            || blue < 0 || blue > 255) {
            throw new IllegalArgumentException();
        }
    }

    public SynchronizedRGB(int red,
                           int green,
                           int blue,
                           String name) {
        check(red, green, blue);
        this.red = red;
        this.green = green;
        this.blue = blue;
        this.name = name;
    }

    public void set(int red,
                    int green,
                    int blue,
                    String name) {
        check(red, green, blue);
        synchronized (this) {
            this.red = red;
            this.green = green;
            this.blue = blue;
            this.name = name;
        }
    }

    public synchronized int getRGB() {
        return ((red << 16) | (green << 8) | blue);
    }

    public synchronized String getName() {
        return name;
    }

    public synchronized void invert() {
        red = 255 - red;
        green = 255 - green;
        blue = 255 - blue;
        name = "Inverse of " + name;
    }
 }

3. 原文翻译

SynchronizedRGB must be used carefully to avoid being seen in an inconsistent state. Suppose, for example, a thread executes the following code:
SynchronizedRGB必须小心使用,以避免被看到处于不一致的状态。例如,假设一个线程执行以下代码

SynchronizedRGB color =
     new SynchronizedRGB(0, 0, 0, "Pitch Black");
 ...
 int myColorInt = color.getRGB();      //Statement 1
 String myColorName = color.getName(); //Statement 2

If another thread invokes color.set after Statement 1 but before Statement 2, the value of myColorInt won’t match the value of myColorName. To avoid this outcome, the two statements must be bound together:
如果另一个线程【在语句1之后但在语句2之前】调用color的set方法,myColorInt的值将不匹配myColorName的值。为了避免这种结果,这两种语句必须结合在一起:

synchronized (color) {
     int myColorInt = color.getRGB();
     String myColorName = color.getName();
 }

三、A Strategy for Defining Immutable Objects(定义不可变对象的策略)

1.原文链接

2.原文翻译

The following rules define a simple strategy for creating immutable objects.
以下规则定义了创建不可变对象的简单策略。
Not all classes documented as “immutable” follow these rules. This does not necessarily mean the creators of these classes were sloppy
并不是所有被记录为“不可变”的类都遵循这些规则。这并不一定意味着这些类的创造者是草率的
— they may have good reason for believing that instances of their classes never change after construction.
他们可能有很好的理由相信他们的类的实例在构造之后永远不会改变。
However, such strategies require sophisticated analysis and are not for beginners.
然而,这种策略需要复杂的分析,不适合初学者。
1.Don’t provide “setter” methods — methods that modify fields or objects referred to by fields.
不要提供“setter”方法——修改字段或字段引用的对象的方法
2.Make all fields final and private.
使所有字段为final和private
3.Don’t allow subclasses to override methods. The simplest way to do this is to declare the class as final. A more sophisticated approach is to make the constructor private and construct instances in factory methods.
不要允许子类重写方法。最简单的方法是将类声明为final。更复杂的方法是将构造函数设为私有,并在工厂方法中构造实例
4.If the instance fields include references to mutable objects, don’t allow those objects to be changed:如果实例字段包含对可变对象的引用,则不允许修改这些对象
·Don’t provide methods that modify the mutable objects.不要提供修改可变对象的方法
·Don’t share references to the mutable objects. Never store references to external, mutable objects passed to the constructor;
不要共享对可变对象的引用。永远不要存储传递给构造函数的外部可变对象的引用
if necessary, create copies, and store references to the copies. Similarly, create copies of your internal mutable objects when necessary to avoid returning the originals in your methods.
如果需要,创建副本,并存储对副本的引用。类似地,在必要时创建内部可变对象的副本,以避免在方法中返回原始对象
Applying this strategy to SynchronizedRGB results in the following steps:将此策略应用于SynchronizedRGB会导致以下步骤
1.There are two setter methods in this class. The first one, set, arbitrarily transforms the object, and has no place in an immutable version of the class.
这个类中有两个setter方法。第一个,设置,任意转换对象,并且在类的不可变版本中没有位置(即在不可变版本中set方法去掉了)
The second one, invert, can be adapted by having it create a new object instead of modifying the existing one.
第二个是invert,可以通过让它创建一个新对象而不是修改现有对象来调整
2.All fields are already private; they are further qualified as final.
所有的字段已经是私有的;他们进一步被限定为final的
3.The class itself is declared final.类本身被声明为final
4.Only one field refers to an object, and that object is itself immutable. Therefore, no safeguards against changing the state of “contained” mutable objects are necessary.
只有一个字段指向一个对象,而该对象本身是不可变的。因此,不再需要防止改变“包含的”可变对象的状态(即不需要再为对象状态被改变引发的不一致问题而烦恼了)
After these changes, we have ImmutableRGB:

3.原文代码

final public class ImmutableRGB {

   // Values must be between 0 and 255.
   final private int red;
   final private int green;
   final private int blue;
   final private String name;

   private void check(int red,
                      int green,
                      int blue) {
       if (red < 0 || red > 255
           || green < 0 || green > 255
           || blue < 0 || blue > 255) {
           throw new IllegalArgumentException();
       }
   }

   public ImmutableRGB(int red,
                       int green,
                       int blue,
                       String name) {
       check(red, green, blue);
       this.red = red;
       this.green = green;
       this.blue = blue;
       this.name = name;
   }


   public int getRGB() {
       return ((red << 16) | (green << 8) | blue);
   }

   public String getName() {
       return name;
   }

   public ImmutableRGB invert() {
       return new ImmutableRGB(255 - red,
                      255 - green,
                      255 - blue,
                      "Inverse of " + name);
   }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dylanioucn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值