String为什么是不可变得?好处是什么?

目录

1.String为什么是不可变得?

1.1 “不可变”的概念?

1.2 怎么实现的?

1.2.1 为什么String类被final修饰?

1.2.2 为什么char value[] 被final修饰?

 2.优点?


最近在研究String,发现有些概念自己搞了很久才搞懂,为了方便有后来者学习,也为了让自己加深一下记忆。在此记录一下,如有错误,还请多多指正。

1.String为什么是不可变得?

1.1 “不可变”的概念?

        这里不可变指的是String指向字符串常量池中的常量是不可变得,但是可以改变引用的地址。并不是指Sting本身被赋值后就不能再改变了。

        当String a 被重新赋值时,不是修改常量池中的值,也就是“abcd”是不可修改的,可以开辟另外一个空间“abcdef”,改变Sting a的引用地址。

1.2 怎么实现的?

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

    /** Cache the hash code for the string */
    private int hash; // Default to 0

首先我们了解一下final的作用

  • final修饰的类,不能被继承。

  • final修饰的方法,不能被重写。

  • final修饰的变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的,也就是说在对其初始化之后便不能再让其指向另一个对象。 

1.2.1 为什么String类被final修饰?

        String类被final修饰目的是:确保它们不会在子类中改变语义。String类是final类,这意味着不允许任何人定义String的子类。就是为了防止大家乱继承String,从而改变String的特性,这样就会打破成为共识的基本约定。

1.2.2 为什么char value[] 被final修饰?

        目的:保证String不变性。(这样才能实现字符串常量池)

问题:被final修饰一定能保证value[]的不变性吗?

        答案:不能

看如下代码: 

    @Test
    public void finalTest02() {
        final char[] value = {'c', 'c', 'c'};
        System.out.println(value);
        //将索引位置为2的修改为b
        value[2] = 'a';
        System.out.println(value);
    }
    /**
     * 结果
     * ccc
     * cca
     */

    @Test
    public void finalTest(){
        final  char[] value = {'a','a','a'};
        char[] value2 = {'b','b','b'};
        value = value2;
        //此时会报错,证明被final修饰不能value不能被重新赋值。
    }

我们通过这段代码可以看出,仅仅被final修饰是不能保证Sting的不变性的。

真正保证String不变性的是

  1. private 关键字可以保证value不被其他类访问和修改。
  2. String 类没有提供修改这个字符串的方法。

 2.优点?

  1. 作为在java中经常被使用和访问的类,保证String的不变性可以实现字符串常量池(在jvm方法区中),不用频繁的创建对象,可以节省内存空间
  2. 因为String是不可变的,多线程对同一个String操作时,不用考虑安全性的问题。因为是线程安全的。
  3. String很适合做Map的key。因为String有个成员变量hash
        /** Cache the hash code for the string */
        private int hash; // Default to 0

    保存的是 String 对象的 HashCode。因为 String 是不可变的,所以对象一旦被创建之后,HashCode 的值也就不可能变化了,我们就可以把 HashCode 缓存起来。这样的话,以后每次想要用到 HashCode 的时候,不需要重新计算,直接返回缓存过的 hash 的值就可以了,因为它不会变,这样可以提高效率,所以这就使得字符串非常适合用作 HashMap 的 key。

### 回答1: 在许多编程语言中,包括Java、Python和C#等,字符串string)通常被设计成不可变的,这意味着一旦字符串被创建,就不能修改它的内容。这是因为字符串在内存中被存储为一系列字符,而这些字符通常被分配在一个连续的内存块中。如果允许修改字符串,那么可能需要更改内存块的大小,这可能会导致性能问题和内存分配问题。 另一个原因是字符串不可变性的优点是它可以使代码更安全。如果字符串是可变的,那么可能会在多个地方修改同一个字符串对象,这可能会导致意想不到的结果。例如,如果两个线程同时修改同一个字符串,就可能会导致数据竞争和并发问题。而如果字符串不可变的,那么它就可以被视为是线程安全的,因为多个线程可以同时访问同一个字符串对象,而不会对其产生任何副作用。 最后,字符串不可变性也有助于提高代码的可读性和维护性。因为不可变的字符串可以确保其值不会在代码的其他部分中被意外地更改,从而使代码更加可预测和易于理解。 ### 回答2: string不可变的,是由于以下几个原因。 首先,字符串不可变性使得其在使用过程中更加高效和安全。由于字符串不可变的,所以可以被多个变量同时引用,而不会发生修改引起的错误。这也意味着字符串在拷贝和传递时只需引用指针,而不必进行真正的复制,这样可以节省内存空间和计算资源。 其次,不可变性保护了字符串的数据完整性和安全性。如果字符串是可变的,那么任何引用该字符串的变量都可以修改其内容,这可能会导致数据被意外改变或被不可信的代码篡改。而不可变性保证了字符串的数据不会被修改,避免了这些潜在的问题。 另外,字符串不可变性还使得字符串可以被用作哈希表的键。由于不可变性保证了字符串的值不会被改变,所以字符串可以通过其值来进行哈希计算,保证了哈希表的键的唯一性和可靠性。 因此,字符串不可变的是为了提高字符串的效率、保护数据的完整性和安全性,以及提供字符串作为哈希表键的能力。这些特性使得字符串在很多编程语言中都选择将其设计为不可变的数据类型。 ### 回答3: String不可变的,主要有以下几个原因。 首先,String被设计为不可变的,是为了增加程序的安全性。当String对象被创建后,其值就不能再被修改。这意味着,一旦一个String对象被赋值后,它的内容就不会再被改变。这样的设计可以避免在程序中意外地对String对象进行修改,保护程序的稳定性和正确性。 其次,不可变的String对象在多线程环境下更加安全。在并发编程中,如果多个线程同时修改一个可变的字符串对象,可能会引发数据竞争和线程安全问题。而不可变的String对象在被创建后,其值不会被修改,因此可以在多线程环境下共享而不需要额外的同步措施。 第三,不可变的String对象有助于提升程序的性能。由于String对象不可变,所以可以被缓存,以便在内存中重复使用。这样可以减少字符串的创建和销毁次数,降低内存的占用和垃圾回收的压力,从而提高程序的执行效率。 最后,不可变的String对象提供了更好的字符串安全性。由于字符串常常用于储存敏感信息,如密码、密钥等,不可变的特性可以避免敏感信息被修改和篡改。在安全敏感的应用中,使用不可变的String对象可以更好地保护数据的机密性和完整性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值