关于后端:深入理解不可变对象

34次阅读

共计 1382 个字符,预计需要花费 4 分钟才能阅读完成。

前言

说到不可变对象,想必大部分人都不会生疏。Java 程序员在日常开发过程中 100% 会用到的 String 对象就属于不可变对象吗,明天咱们就来聊聊不可变对象这个话题。

什么是不可变对象

《Effective Java》中是这样定义不可变对象的:

不可变对象(Immutable Object):对象一旦被创立后,对象所有的状态及属性在其生命周期内不会产生任何变动。

简略的说,就是一个对象在创立后,不能对该对象进行任何更改。比方上面这段代码:

public class ImmutableObject {
    private int value;
     
    public ImmutableObject(int value) {this.value = value;}
     
    public int getValue() {return this.value;}
}

因为 ImmutableObject 不提供任何 setter 办法,并且成员变量 value 是根本数据类型,getter 办法返回的是 value 的拷贝,所以一旦 ImmutableObject 实例被创立后,该实例的状态无奈再进行更改,因而该类具备不可变性。

String 类

咱们常见的 String 类,为什么说字符串是不可变的?我的代码中常常扭转 String 的值啊!如下所示:

String string = "ABC";
string = string.concat("DE");

这样,下面的字符串不就扭转成 ”ABCDE” 了么?然而实际上,咱们失去的曾经是一个新的字符串。

程序会在堆中从新创立一个 ”ABCDE” 字符串,和 ”ABC” 并不是同一个对象。

所以,一旦一个 string 对象在内存 (堆) 中被创立进去,他就无奈被批改。而且,String 类的所有办法都没有扭转字符串自身的值,都是返回了一个新的对象。

string 类如何设计成不可变

  1. String 类被 final 关键字润饰,所以它不会有子类,这就意味着没有子类能够重写它的办法,扭转它的行为。
  2. String 类的数据存储在 char[] 数组中,而这个数组也被 final 关键字润饰了,这就示意 String 对象是没法被批改的,只有初始化一次,值就确定了。

不可变的益处

安全性

String 是 Java 中最根底也是最长应用的类,常常用于存储一些敏感信息,例如用户名、明码、网络连接等。因而,String 类的安全性对于整个应用程序至关重要。

节俭空间(字符串常量池)

通过应用常量池,内容雷同的字符串能够应用同一个对象,从而节俭内存空间。如果 String 是可变的,试想一下,当字符串常量池中的某个字符串对象被很多中央援用时,此时批改了这个对象,则所有援用的中央都会扭转,这可能会导致预期之外的状况。

性能

String 被广泛应用于 HashMap、HashSet 等哈希类中,当对这些哈希类进行操作时,例如 HashMap 的 get/put,hashCode 会被频繁调用。

线程平安

String 对象是不可批改的,如果线程尝试批改 String 对象,会创立新的 String,所以不存在并发批改同一个对象的问题。

因为不可变性,String 的 hashCode 只须要计算 1 次后就能够缓存起来,因而在哈希类中应用 String 对象能够晋升性能。

总结

因为字符串是不可变的,因而它们的援用能够被视为一般变量,能够在办法之间和线程之间传递它们,而不用放心它所指向的理论字符串对象是否会扭转。

本文由 mdnice 多平台公布

正文完
 0