是什么让 String 不可变?
What makes String immutable?
我知道字符串是不可变的,但为什么呢?
哪个概念使字符串 class 不可变?
public class Mainclass
{
public static void main(String[] args)
{
String s = "Example";
s.toUpperCase();
System.out.println(s);
}
}
结果:
Example
任何 class 不能被子class编辑并且不提供任何修改其状态的方法——例如通过不提供任何设置器、将其字段保持私有等——是不可变的。没有什么特别的魔法。
String 是不可变的,因为无法更改其内部表示的内容,无法获得对其内部表示的引用,也无法对其进行子类化。这意味着无论您对 String 做什么,都无法更改其内容。
像toUpperCase()
这样的方法实际上做的是return一个新字符串,它与旧字符串具有相同的内容。但是,新的 String 是一个单独的对象。对初始字符串的引用现在不会指向新字符串。
如果您想打印出 toUpperCase()
的结果,请按以下方式进行操作:
String s="Example";
String upperCase = s.toUpperCase();
System.out.println(upperCase);
编辑:引用与对象
Java 中的变量是对对象的引用。 recerence 本质上是一个指示 Java "your object is here" 的指针,指向某个内存位置。但是引用和对象不是一回事。让我们看下面的例子
String s = "Test";
String a = s;
String s = "another test"
我在这里所做的是声明一个名为 s
的引用,并将其指针设置为一个新创建的对象 - 在本例中是一个值为 "Test"
的字符串。然后我声明另一个引用 a
并将其设置为引用 s
引用的同一个对象。请注意,有两个引用但只有一个对象。
从那里我将引用 s 更改为指向不同的对象 - 在本例中为值为 "another test"
的字符串。这将创建一个新对象,尽管引用被重用。但是,引用 a
仍然指向原始对象,该对象保持不变。如果我们做 println(a)
它仍然会打印 "Test"
。这是因为对象本身是不可变的。任何指向它的东西都会 return 相同的值。我可以将引用指向其他地方,但不能更改对象。
将变量想象成 phone 书中的条目。如果我为某人输入一个条目并说他的姓氏是 "BOB",然后有人出现并将其划掉并写为 "ALICE",这不会突然改变 Bob 的性别或他的名字。 BOB 不会自发地变成 ALICE,因为有人重写了我的 phone 书。它只是改变了我 phone 书中的价值,而不是实际的人。我希望这个比喻有所帮助。
这些是您可以使任何 type/class 不可变的步骤
1) 不要提供“setter”方法——修改字段或字段引用的对象的方法。
2) 将所有字段设为最终字段和私有字段。
3) 不允许成为 sub class,使 class 最终。
4) 具有可变实例变量时要特别注意。
其中一个原因是安全性。网络连接的参数是字符串类型。应该不容易修改。
我知道字符串是不可变的,但为什么呢?
哪个概念使字符串 class 不可变?
public class Mainclass
{
public static void main(String[] args)
{
String s = "Example";
s.toUpperCase();
System.out.println(s);
}
}
结果:
Example
任何 class 不能被子class编辑并且不提供任何修改其状态的方法——例如通过不提供任何设置器、将其字段保持私有等——是不可变的。没有什么特别的魔法。
String 是不可变的,因为无法更改其内部表示的内容,无法获得对其内部表示的引用,也无法对其进行子类化。这意味着无论您对 String 做什么,都无法更改其内容。
像toUpperCase()
这样的方法实际上做的是return一个新字符串,它与旧字符串具有相同的内容。但是,新的 String 是一个单独的对象。对初始字符串的引用现在不会指向新字符串。
如果您想打印出 toUpperCase()
的结果,请按以下方式进行操作:
String s="Example";
String upperCase = s.toUpperCase();
System.out.println(upperCase);
编辑:引用与对象
Java 中的变量是对对象的引用。 recerence 本质上是一个指示 Java "your object is here" 的指针,指向某个内存位置。但是引用和对象不是一回事。让我们看下面的例子
String s = "Test";
String a = s;
String s = "another test"
我在这里所做的是声明一个名为 s
的引用,并将其指针设置为一个新创建的对象 - 在本例中是一个值为 "Test"
的字符串。然后我声明另一个引用 a
并将其设置为引用 s
引用的同一个对象。请注意,有两个引用但只有一个对象。
从那里我将引用 s 更改为指向不同的对象 - 在本例中为值为 "another test"
的字符串。这将创建一个新对象,尽管引用被重用。但是,引用 a
仍然指向原始对象,该对象保持不变。如果我们做 println(a)
它仍然会打印 "Test"
。这是因为对象本身是不可变的。任何指向它的东西都会 return 相同的值。我可以将引用指向其他地方,但不能更改对象。
将变量想象成 phone 书中的条目。如果我为某人输入一个条目并说他的姓氏是 "BOB",然后有人出现并将其划掉并写为 "ALICE",这不会突然改变 Bob 的性别或他的名字。 BOB 不会自发地变成 ALICE,因为有人重写了我的 phone 书。它只是改变了我 phone 书中的价值,而不是实际的人。我希望这个比喻有所帮助。
这些是您可以使任何 type/class 不可变的步骤
1) 不要提供“setter”方法——修改字段或字段引用的对象的方法。
2) 将所有字段设为最终字段和私有字段。
3) 不允许成为 sub class,使 class 最终。
4) 具有可变实例变量时要特别注意。
其中一个原因是安全性。网络连接的参数是字符串类型。应该不容易修改。