更改字符串文字时会发生什么?
我想将字符串文字更改为全大写字母。 这是我的代码:
// a and b are the same literal String a = "Test"; String b = "Test"; // now I want to change all b's letter // into uppercases, but fail. b.toUpperCase(); System.out.println("a = " + a + ", " + "b = " + b); // print: a = Test, b = Test String c = "Test1"; System.out.println("c = " + c + " , c.toUpperCase() = " + c.toUpperCase()); // print: c = Test1 , c.toUpperCase() = TEST1 // change letters of "Test" literal // into uppercase and success System.out.println("Test".toUpperCase()); // print: TEST
我的问题是:1。b不能改成大写的一个,但c
和"Test"
可以。 为什么?
我所知道的是:1。a和b
引用字符串池中的同一个对象。 2.字符串是不可变的,但似乎与此问题无关。
字符串是不可变的。 所以对于改变b:
b = b.toUpperCase();
每次执行更改String的操作时,都会创建一个新的String对象。 所以你需要改变对象的引用。
更改字符串文字时会发生什么?
没有。 那是字符串文字对象无法改变的,因为正如你所指出的那样,你已经知道,它是不可变的。 可以引用它(变量如a
, b
, c
)来引用其他字符串,但该字符串实例不会从"Test"
更改。
但要解释你的代码:
这是b
和c
之间的区别:
b.toUpperCase(); //there's a result from this function you are not using System.out.println("b = " + b); System.out.println("c = " + c.toUpperCase()); //you're using the result here.
字符串是不可变的,但似乎与此问题无关
它是相关的,如果你知道它是不可变的,很明显b
不能改为大写,并且必须创建一个新的字符串作为toUpperCase
的结果,因此你必须使用它。 但是可以使b
引用新字符串,这不会影响仍然引用旧字符串的任何其他内容:
b = b.toUpperCase(); //b now is set to the new upper case string System.out.println("b = " + b);
我的问题是:1。b不能改成大写的一个,但c和“Test”可以。 为什么?
我的答案是当你打印c.toUpperCase()
,变量c
根本没有改变 。
您只是返回另一个基于c
的内容构建为大写的String 。
这同样适用于String "test"
。
即使你这样做,你只是指向一个新的String:
String c = "Test1"; c = c.toUpperCase();
这是发生的事情:
//String c = "Test1"; +-------+ |"Test1"| <--- c +-------+ //c = c.toUpperCase(); +-------+ |"TEST1"| <--- c +-------+ +-------+ |"Test1"| <--- waiting to be collected by Garbage collector +-------+
字符串是不可变的,但似乎与此问题无关
实际上,它与这个问题非常相关
b
不能改为大写
因为toUpperCase()
通过对调用字符串进行操作来返回一个新字符串,所以请使用
b = b.toUpperCase();
c和“测试”可以。 为什么?
c
尚未更改,其结果已添加到System.out.println()
的字符串中
让我们逐行采用您的代码,请阅读我的评论:
// a and b are the same literal /* FIRST POINT : Here you assigned two times the same value "Test", BUT IT'S 2 DIFFERENT OBJECTS IN MEMORY */ String a = "Test"; String b = "Test"; // now I want to change all b's letter // into uppercases, but fail. /* SECOND POINT : Here you just apply a function (toUpperCase()) on "b" object. This function returns a string object but YOU ARE NOT DOING ANYTHING WITH IT ie displaying it or reassigning it to another variable! */ b.toUpperCase(); System.out.println("a = " + a + ", " + "b = " + b); // THAT'S WHY IT STILLS PRINT // print: a = Test, b = Test String c = "Test1"; System.out.println("c = " + c + " , c.toUpperCase() = " + c.toUpperCase()); /* THIRD POINT : Here you apply a function (toUpperCase()) on "c" object but this time YOU ARE REUSING THE RETURN STRING :) ie you are displaying it! */ // print: c = Test1 , c.toUpperCase() = TEST1 // change letters of "Test" literal // into uppercase and success /* LAST POINT : Here you do the same as you did before on "c" object YOU ARE REUSING THE RETURN STRING AGAIN :) ie you are displaying it! */ System.out.println("Test".toUpperCase()); // print: TEST
最后但并非最不重要的是,对字符串对象调用toUpperCase()/ toLowerCase()函数永远不会重新分配对象的值。 这些函数只返回一个字符串。
重新分配字符串值的方法是通常的方法:
String a = "Test"; a = a.toUpperCase();
请注意,正如许多人所说,这将在内存“TEST”中创建另一个对象并将其分配给“a”,然后您的旧字符串“Test”将成为垃圾收集器的候选者。
我希望现在更有意义。
干杯,
你需要像这样改变,因为strings
是immutable
public static void main(String[] args) { // a and b are the same literal String a = "Test"; String b = "Test"; // now I want to change all b's letter // into uppercases, but fail. b= b.toUpperCase(); System.out.println("a = " + a + ", " + "b = " + b); // print: a = Test, b = Test String c = "Test1"; // c=c.toUpperCase(); System.out.println("c = " + c + " , c.toUpperCase() = " + (c=c.toUpperCase())); // print: c = Test1 , c.toUpperCase() = TEST1 // change letters of "Test" literal // into uppercase and success System.out.println("Test".toUpperCase()); // print: TEST
我建议你研究一下Java API 。 通过使用toUpperCase,您将获得一个新的String对象。 如果要使用新文本打印变量,则应将新对象分配给变量。 在c的情况下,您打印出对象的返回“新”内容。 变量c将再次为小写。