这怎么被认为是不可改变的?

时间:2016-01-27 23:20:38

标签: java

根据我对Java的理解,String是不可变的。所以以下内容不会连接,只会给我输出 app ,证明它是不可变的。我知道了。

String apple = new String("app");
apple.concat("le");
System.out.println(apple);

但是我可以在用一些值初始化之后更改String的值。不管怎样,这不是一成不变的吗?

String orange = "ora";
orange = "orange";
System.out.println(orange);

6 个答案:

答案 0 :(得分:7)

对象是不可变的,参考不是。您可以使用 orange =“Orange”随时更改引用但不更改对象。你只是放弃旧的,并将引用附加到新的。

答案 1 :(得分:2)

当你这样做时:

orange = "orange";

幕后发生的事情是:

orange = new String("orange");

即,orange作为引用String被修改。它只是指向一个不同的String实例。

在此声明中:

apple.concat("le");

会发生什么情况,您创建的新String对象是apple.concat(new String("le"))的结果,但您没有指定它...

但是你又在这里处理字符串;字符串是Java中为数不多的具有内置行为的类之一,例如:

final String x = "a" + "b";

实际上转化为:

final String x = new StringBuilder("a").append("b").toString();

你已经走进了大黄蜂的巢穴。

答案 2 :(得分:1)

String类的实例是不可变的。 apple 变量不是不可变的,但如果您将其声明为final,那就是它。

例如,以下代码是变异对象:

Person p = new Person("John");
p.setName("Jenny"); // <-- mutating

不可变对象(如StringInteger,...)没有改变对象状态的方法。

相反,以下代码正在更改p的值,但不会改变任何对象:

Person p = new Person("John");
p = new Person("Jenny");

p只是更新为引用不同的Person对象。原来的约翰&#34;对象仍然存在(直到垃圾收集)。

现在,如果将p定义为final,那么它(变量)也将是不可变的:

final Person p = new Person("John");
// Cannot: p = new Person("Jenny");

在您的特定情况下,concat不会改变String,它会创建一个新字符串并将其返回,因此您需要:

String apple = new String("app");
apple = apple.concat("le");
System.out.println(apple); // prints "apple"

此处变量已更新,但不会更新String对象。

答案 3 :(得分:0)

根据维基百科,一个不可变的对象是:

  

一个对象,其状态在创建后无法修改。

但是,您并非修改原始橙色String object"ora"):您正在创建新的String object"orange"),此对象已分配到变量。

容易成为蛋糕

如果这没有意义,那就这样想吧。假设一些Object是一块巧克力蛋糕,你可以添加糖衣或切出这块蛋糕的一部分,而不会实际改变蛋糕的身份。但是,如果你想将它改成红色天鹅绒蛋糕,你必须制作一个蛋糕,因为你不能修改巧克力蛋糕,使其成为红色天鹅绒蛋糕(用于实用目的)的原始。一个不可变的对象意味着你不能切割或者冰......那么你可以用一块新的蛋糕代替它。

答案 4 :(得分:0)

orange = "orange"仅表示orange指向新的String实例,而不是旧实例("ora")。

不变性意味着一旦创建了对象的状态就无法改变它。您还没有改变orange所指的字符串实例的状态;你刚才让它引用了一个新实例。更改对象的状态要求您在该对象上调用更改其状态的方法,或者修改其可公开访问的属性之一。

您还会混淆对象的不变性和引用的不变性。要使引用不可变(即,确保在初始化后无法指向其他内容),请使用final关键字。

所以如果你有:

final String orange = "ora";
orange = "orange";

您现在会收到错误,因为引用是不可变的,无法重新分配。

答案 5 :(得分:0)

对象是不可变的,而引用则不是。您可以更改引用但不能更改对象。

添加示例以使我们更清楚

String orange1 = "ora";
String orange2 = orange1;
System.out.println("orange1: " + orange1 +  " , orange2: " + orange2);
System.out.println("----------------------");
orange2 = "orange";
System.out.println("orange1: " + orange1 +  " , orange2: " + orange2);