java中字符串对象的不变性

时间:2014-10-05 17:29:38

标签: java string

我是编程中的菜鸟,现在正在学习Java。 我已经读过Strings在Java中是不可变的。但是,我有一个问题。

public class Immutable {

    public static void main (String[ ] args) 
    {
        new Immutable().run(); 
    } // method main

    public void run() 
    {
        String s = "yEs";
        String p = "Do";

        p=p.toUpperCase();
        s=s.toLowerCase();
        //Here above I'm able to change the content of the string object. 
        //Why is it said Immutable??

        p = new String("DoPe");

        System.out.println(p);
        // Here I'm taking it as I'm creating new object and I'm assigning it to 'p'
        //rather than changing the previously assigned object. so it's immutable

        //Is my understanding correct??


        flip (s); 
        System.out.println(s);
        //Why does assigning a new object using a method doesn't work
        //while if I do it explicitly, it works(as I've done for 'p', see above)

    } // method run

    public void flip (String t) 
    {
        System.out.println(t);
        t = new String ("no");
        System.out.println(t);

        t = "nope";
        System.out.println(t);
    } // method flip

} // class Immutable

请在我的评论中查看问题。

修订:

public class Immutable {

    public static void main (String[] args) 
    {
        new Immutable().run(); 
    } // method main

    public void run() 
    {
        String s = "yEs";
        String p = "Do";

        int [] arr = new int[5];

        for (int i = 0; i < 5; i++)
            arr[i] = i;

        System.out.println("Value in the calling function before the altering is done: "+Arrays.toString(arr));

        alter(arr);
        System.out.println("Value in the calling function after the altering is done: "+Arrays.toString(arr));

        p = p.toUpperCase();
        s = s.toLowerCase();
        //Here above I'm able to change the content of the string object. 
        //Why is it said Immutable??

        p = new String("DoPe");

        System.out.println(p);
        // Here I'm taking it as I'm creating new object and I'm assigning it to 'p'
        //rather than changing the previously assigned object. so it's immutable

        //Is my understanding correct??

        System.out.println("Value of string in the calling function before the altering is done: "+s);
        flip (s); 
        System.out.println("Value of string in the calling function after the altering is done: "+s);
        //Why does assigning a new object using a method doesn't work
        //while if I do it explicitly work(as I've done for 'p', see above)

    } // method run

    public void flip (String t) 
    {
        System.out.println("Value of string in the called function, before altering: "+t);
        t = new String ("no");
        System.out.println("Value of string in the called function, after Altering: "+t);

        t = "nope";
        System.out.println(t);
    } // method flip

    public void alter(int[] a)
    {
        System.out.println("Value in the called function, before altering: "+Arrays.toString(a));
        a[3] = 50;
        System.out.println("Value in the called function, after Altering: "+Arrays.toString(a));
    }

} // class Immutable

修改适用于数组,但不适用于字符串。 这是字符串被称为不可变的原因吗?

我错过了什么吗?

5 个答案:

答案 0 :(得分:2)

  

上面我可以更改字符串对象的内容。为什么说Immutable ??

您不会更改String的内容,您创建一个新的String对象并将其与变量链接,旧对象将被删除。

  

我在这里接受它,因为我正在创建新对象,并且我将其分配给&#39; p&#39;而不是改变以前分配的对象。所以它是不可改变的。我的理解是否正确?

是的,这实际上与您上面提到的一个问题相同,但String对象是由其实例方法之一创建的。

  

为什么使用方法分配新对象并不会有效,如果我明确地工作(因为我已经完成了&#39; p&#39;,见上文)

这是因为String的不变性。 Java是按值传递的,但您的方法需要是按指针传递。由于您无法更改String的内容(您只能创建一个新的String对象),因此您需要返回String。

答案 1 :(得分:1)

你没有改变字符串对象的内容,你正在改变哪个变量指向内存中的哪个对象。

变量只是指向内存中对象的指针,而不是实际对象。

答案 2 :(得分:1)

您不会更改字符串对象的内容。您正在创建新对象,并使sp指向新对象。

答案 3 :(得分:1)

//Here above I'm able to change the content of the string object. 
//Why is it said Immutable??

您没有更改字符串的内容,只是创建了一个新的String并将其引用分配给您的String变量。这也回答了你的第二条评论。

//Why does assigning a new object using a method doesn't work
//while if I do it explicitly work(as I've done for 'p', see above)

因为Java方法不是通过引用传递的。有关详细信息,请参阅this question

答案 4 :(得分:0)

我相信你对事情感到困惑。 总的来说,我明白你的意思。 你相信你通过p = new String("DoPe");“改变了”p,这是正确的,但当你致电flip (s);时,s不会发生同样的事情 好吧,调用它不会“改变”因为你的函数翻转只需要一个字符串并在内部修改它就是这样。 为了使用函数“更改”,您必须进行此修改:

1 s= flip (s); (s接收函数的返回值) 2.函数flip应该返回一个String而不是void

public String flip (String t) // String instead of void 
    {
        System.out.println(t);
        t = new String ("no");
        System.out.println(t);

        t = "nope";
        System.out.println(t);
    return t; //returns the String t
    }