什么使String不可变?

时间:2015-04-13 19:05:45

标签: java string class immutability

我知道String是不可变的,但为什么呢?

哪个概念使字符串类不可变?

public class Mainclass
{
    public static void main(String[] args) 
    {
        String s = "Example";
        s.toUpperCase();
        System.out.println(s);
    }
}

结果:

Example

4 个答案:

答案 0 :(得分:6)

字符串是不可变的,因为无法更改其内部表示的内容,无法获得对其内部表示的引用,并且它不能被子类化。这意味着无论您对String执行什么操作,都无法更改其内容。

toUpperCase()这样的方法实际上是返回一个新的String,它与旧的String具有相同的内容。但是,新String是一个单独的对象。对初始字符串的引用现在不会指向新字符串。

如果您想打印toUpperCase()的结果,请执行以下操作:

String s="Example";
String upperCase = s.toUpperCase();
System.out.println(upperCase);

编辑:引用与对象

Java中的变量是对象的引用。一个recerence本质上是一个指针,告诉Java“你的对象在这里”,指的是一些内存位置。然而,引用和对象不是一回事。让我们看一下以下的例子

String s = "Test";
String a = s;
String s = "another test"

我在这里所做的是声明一个名为s的引用,并将其指针设置为一个新创建的对象 - 在本例中是一个值为"Test"的String。然后我声明另一个引用a并将其设置为引用s引用的同一对象。请注意,有两个引用但只有一个对象。

从那里我将引用更改为指向另一个对象 - 在本例中为一个值为"another test"的String。尽管重用了引用,但这会创建一个新对象。但是,引用a仍然指向原始对象,该对象保持不变。如果我们执行println(a),它仍然会打印"Test"。这是因为对象本身是不可变的。任何指向它的东西都会返回相同的值。我可以将引用指向其他地方,但不能更改对象。

考虑电话簿中的条目等变量。如果我为某人输入一个条目并且说他的姓氏是“BOB”,并且有人后来出现并且将其翻过来写“ALICE”,这并不会突然改变Bob的性别或他的名字。 BOB并没有自发地变成驴友,因为有人改写了我的电话簿。它只是改变了我的电话簿中的价值,而不是实际的人。我希望这个比喻有所帮助。

答案 1 :(得分:1)

任何不能被子类化的类,并且不提供任何修改其状态的方法 - 例如通过不提供任何setter,保持其字段私有等 - 是不可改变的。没有特别的魔力。

答案 2 :(得分:0)

这些步骤可以使任何类型/类成为不可变的

1)不要提供“setter”方法 - 修改字段引用的字段或对象的方法。

2)将所有字段设为最终字段并保密。

3)不允许成为子类,使类最终。

4)具有可变实例变量时要特别注意。

答案 3 :(得分:0)

其中一个原因是安全性。网络连接的参数是String的类型。它不容易被修改。