更改字符串文字时会发生什么?

时间:2016-03-05 12:06:42

标签: java

我想将字符串文字更改为全大写字母。这是我的代码:

    // 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. ab引用字符串池中的同一对象。     2.字符串是不可变的,但它似乎与这个问题无关。

7 个答案:

答案 0 :(得分:4)

字符串是不可变的。所以对于改变b:

b = b.toUpperCase(); 

每当你做一些改变String的事情时,就会创建一个新的String对象。所以你需要改变对象的引用。

答案 1 :(得分:2)

  

字符串是不可变的,但似乎与此问题无关

实际上,它与问题

非常相关
  

b无法更改为大写

因为toUpperCase()通过对调用字符串执行操作来返回新字符串,所以请使用

b = b.toUpperCase();

  

c和"测试"能够。为什么呢?

c尚未更改,其结果已添加到System.out.println()

中的字符串中

答案 2 :(得分:1)

  

更改字符串文字后会发生什么?

无。那是字符串文字对象无法改变的,因为正如你所指出的那样,你已经知道,它是不可变的。引用它(abc等变量)可以引用其他字符串,但该字符串实例不会从"Test"更改。

但要解释一下你的代码:

这是bc

之间的差异
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 无法更改为大写,并且必须创建一个新字符串{{{} 1}}因此你必须使用它。但是toUpperCase可以引用新字符串,这不会影响b或其他仍然引用旧字符串的内容:

a

答案 3 :(得分:1)

  

我的问题是:1。b不能改成大写的一个,但c和“Test”可以。为什么呢?

我的回答是,当您打印c.toUpperCase()时,变量c 根本没有更改

您只是返回 另一个字符串 ,它是根据c的内容构建为大写的。

同样适用于字符串"test"

即使你这样做,你只是将c指向一个新的字符串:

String c = "Test1";
c = c.toUpperCase();  

这就是发生的事情:

//String c = "Test1";
+-------+
|"Test1"| <--- c
+-------+

//c = c.toUpperCase();  
+-------+
|"TEST1"| <--- c
+-------+
+-------+
|"Test1"| <--- waiting to be collected by Garbage collector
+-------+

答案 4 :(得分:1)

让我们逐行采用您的代码,请阅读我的评论:

// 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
   i.e. 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 :)
   i.e. 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 :)
   i.e. you are displaying it!
   */
System.out.println("Test".toUpperCase());
// print: TEST

最后但并非最不重要的是,对字符串对象调用toUpperCase()/ toLowerCase()函数永远不会重新分配对象的值。这些函数只返回一个字符串。

重新分配字符串值的方法是通常的方法:

String a = "Test";
a = a.toUpperCase();

请注意,正如许多人所说,这将在内存“TEST”中创建另一个对象并将其分配给“a”,然后您的旧字符串“Test”将成为垃圾收集器的候选者。

我希望现在更有意义。

干杯,

答案 5 :(得分:0)

您需要更改此内容,因为stringsimmutable

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

答案 6 :(得分:0)

我建议您查看Java API。通过使用toUpperCase,您将获得一个新的String对象。如果要使用新文本打印变量,则应将新对象分配给变量。在c的情况下,您将打印出已退回的&#34; new&#34;对象的内容。变量c将再次为小写。