java中的可变和不可变String之间有什么区别

时间:2014-08-05 12:15:24

标签: java string immutability mutable stringbuffer

据我所知,

可以更改可变字符串,并且 无法更改不可变的字符串。

这里我想像这样改变String的值,

String str="Good";
str=str+" Morning";

和其他方式是,

StringBuffer str= new StringBuffer("Good");
str.append(" Morning");

在这两种情况下,我都试图改变str的价值。任何人都可以告诉我,这两种情况有什么不同,并给我清晰的可变和不可变对象的图片。

10 个答案:

答案 0 :(得分:81)

案例1:

String str = "Good";
str = str + " Morning";

在上面的代码中,您可以创建3个String对象。

  1. "良好的"它进入 String Pool
  2. "早晨"它也会进入 String Pool
  3. "早安"通过连接" Good"创建和"早晨&#34 ;.这家伙继续
  4. 注意:字符串始终不可变。没有,像可变字符串这样的东西。 str只是引用,最终指向"早安"。实际上,正在处理1对象。您有3个不同的String个对象。


    案例2:

    StringBuffer str = new StringBuffer("Good"); 
    str.append(" Morning");
    

    StringBuffer包含一系列字符。它与<{1}} 相同。 上面的代码将字符添加到现有数组中。实际上,String是可变的,其StringBuffer表示不是。

答案 1 :(得分:11)

  

java中可变和不可变的String之间有什么区别

不可改变的存在,可变的不要。

答案 2 :(得分:7)

在Java中,所有字符串都是不可变的。当您尝试修改String时,您真正在做的是创建一个新的。但是,当您使用StringBuilder时,实际上是在修改内容,而不是创建新内容。

答案 3 :(得分:5)

Java String是不可变的。

在第一个示例中,您要将引用更改为String,从而为其分配另外两个Strings组合的值:str + " Morning"

相反,可以通过其方法修改StringBuilderStringBuffer

答案 4 :(得分:3)

当你说str时,你应该小心你的意思:

  • 您的意思是变量 str吗?

  • 或者您是指str引用的对象

StringBuffer示例中,您没有改变str的值,而在您的String示例中,您并未改变String对象的状态。

体验差异的最痛苦的方式是:

static void change(String in) { 
  in = in + " changed";
}

static void change(StringBuffer in) {
  in.append(" changed");
}

public static void main(String[] args) {
   StringBuffer sb = new StringBuffer("value");
   String str = "value";
   change(sb);
   change(str);
   System.out.println("StringBuffer: "+sb);
   System.out.println("String: "+str);
}

答案 5 :(得分:3)

Java中的

字符串 不可变 。但是,在编程上下文中 mutable 的意思是第一个问题。考虑以下课程,

public class Dimension {
    private int height;

    private int width;

    public Dimenstion() {
    }

    public void setSize(int height, int width) {
        this.height = height;
        this.width = width;
    }

    public getHeight() {
        return height;
    }

    public getWidth() {
        return width;
    }
}

现在,在创建Dimension实例后,我们可以随时更新它的属性。注意,如果在其他意义状态中的任何属性可以更新为该类的实例,那么它被认为是可变的。我们总能做到以下,

Dimension d = new Dimension();
d.setSize(10, 20);// Dimension changed
d.setSize(10, 200);// Dimension changed
d.setSize(100, 200);// Dimension changed

让我们以不同的方式看到我们可以用Java创建一个String。

String str1 = "Hey!";
String str2 = "Jack";
String str3 = new String("Hey Jack!");
String str4 = new String(new char[] {'H', 'e', 'y', '!'});
String str5 = str1 + str2;
str1 = "Hi !";
// ...

所以,

  1. str1str2是在字符串常量池
  2. 中创建的字符串文字
  3. str3str4str5是放置在堆内存中的字符串对象
  4. str1 = "Hi!";在字符串常量池中创建"Hi!",与"Hey!"之前引用的str1完全不同。
  5. 这里我们创建String文字或String对象。两者都不一样,我建议你阅读以下帖子以了解更多信息。

    在任何String声明中,有一件事是常见的,它不会被修改但会被创建或转移到其他。

    String str = "Good"; // Create the String literal in String pool
    str = str + " Morning"; // Create String with concatenation of str + "Morning"
    |_____________________|
           |- Step 1 : Concatenate "Good"  and " Morning" with StringBuilder
           |- Step 2 : assign reference of created "Good Morning" String Object to str
    
      

    String如何变为不可变?

    这是不变的行为,意味着,一旦分配的值无法以任何其他方式更新。 String类在内部保存字符数组中的数据。而且,类被创建为不可变的。看一下这个策略来定义不可变类。

    转移引用并不意味着您更改了它的值。如果你可以更新String类中场景后面的字符数组,那将是可变的。但实际上,该阵列将被初始化一次并在整个程序中保持不变。

      

    为什么StringBuffer是可变的?

    正如您已经猜到的,StringBuffer类本身是可变的,因为您可以直接更新它的 state 。与String类似,它也在字符数组中保存值,您可以通过不同的方法操作该数组即。追加,删除,插入等直接更改字符值数组。

答案 6 :(得分:1)

在Java中,所有字符串均为immutable(不能更改)。 当您尝试修改字符串时,您真正要做的是创建一个新的字符串。

以下创建字符串对象的方法

  1. 使用字符串文字

    String str="java";
    
  2. 使用新关键字

    String str = new String("java");
    
  3. 使用字符数组

    char[] helloArray = { 'h', 'e', 'l', 'l', 'o', '.' };
    
    String helloString = new String(helloArray);   
    

进入字符串不变性,仅表示不可修改或不可更改

让我们举一个例子

我正在将值初始化为String文字

String s="kumar";

下面,我将使用hashcode()显示位置地址的十进制表示形式

System.out.println(s.hashCode());

仅打印字符串s的值

System.out.println("value "+s);

好的,这次我将值“ kumar”初始化为s1

String s1="kumar";   // what you think is this line, takes new location in the memory ??? 

好的,我们通过显示我们创建的s1对象的哈希码进行检查

System.out.println(s1.hashCode());

好的,让我们检查下面的代码

String s2=new String("Kumar");
    System.out.println(s2.hashCode());  // why this gives the different address ??

好的,最后检查一下下面的代码

String s3=new String("KUMAR");
    System.out.println(s3.hashCode());  // again different address ???

是的,如果您看到字符串's'和's1'具有相同的哈希码,因为's'和's1'持有的值与'kumar'相同

让我们考虑一下字符串's2'和's3',这两个字符串哈希码在意义上似乎是不同的,它们都存储在不同的位置,因为您看到它们的值是不同的。

因为s和s1哈希码相同,因为这些值相同并且存储在同一位置。

示例1: 尝试下面的代码并逐行分析

public class StringImmutable {
public static void main(String[] args) {

    String s="java";
    System.out.println(s.hashCode());
    String s1="javA";
    System.out.println(s1.hashCode());
    String s2=new String("Java");
    System.out.println(s2.hashCode());
    String s3=new String("JAVA");
    System.out.println(s3.hashCode());
}
}

示例2:尝试下面的代码并逐行分析

public class StringImmutable {
    public static void main(String[] args) {

        String s="java";
        s.concat(" programming");  // s can not be changed "immutablity"
        System.out.println("value of s "+s);
        System.out.println(" hashcode of s "+s.hashCode());

        String s1="java";
        String s2=s.concat(" programming");   // s1 can not be changed "immutablity" rather creates object s2
        System.out.println("value of s1 "+s1);
        System.out.println(" hashcode of s1 "+s1.hashCode());  

        System.out.println("value of s2 "+s2);
        System.out.println(" hashcode of s2 "+s2.hashCode());

    }
}

好的,让我们看看可变和不可变之间有什么区别。

可变(可变)与不可变(不变)

public class StringMutableANDimmutable {
    public static void main(String[] args) {


        // it demonstrates immutable concept
        String s="java";
        s.concat(" programming");  // s can not be changed (immutablity)
        System.out.println("value of s ==  "+s); 
        System.out.println(" hashcode of s == "+s.hashCode()+"\n\n");


        // it demonstrates mutable concept
        StringBuffer s1= new StringBuffer("java");
        s1.append(" programming");  // s can be changed (mutablity)
        System.out.println("value of s1 ==  "+s1); 
        System.out.println(" hashcode of s1 == "+s1.hashCode());


    }
}

还有其他问题吗??请写上...

答案 7 :(得分:0)

我使用输出注释修改了william的代码以便更好理解

   static void changeStr(String in) { 
      in = in+" changed";
      System.out.println("fun:"+in); //value changed 
    }
    static void changeStrBuf(StringBuffer in) {
      in.append(" changed");   //value changed
    }

    public static void main(String[] args) {
       StringBuffer sb = new StringBuffer("value");
       String str = "value";
       changeStrBuf(sb);
       changeStr(str);
       System.out.println("StringBuffer: "+sb); //value changed
       System.out.println("String: "+str);       // value 
    }

在上面的代码中,查看main()和changeStr()中str的值,即使你在changeStr()中改变str的值它只影响那个函数,但是在main函数中,值是没有改变,但它不是StringBuffer的情况..

在StringBuffer中,更改的值会受到全局影响..

因此String是不可变的,StringBuffer是可变的......

在Simple中,无论你改变为String对象,只会影响到该函数。转到String Pool。但没有改变......

答案 8 :(得分:0)

可变变量是其值可能在适当位置变化的变量,而在不可变变量中,变量值不会发生。修改不可变变量将重建相同的变量。

答案 9 :(得分:0)

Mutable意味着您将相同的引用保存到变量并更改其内容但不可变您不能更改内容但是声明新引用包含新旧变量的值

实施例 不可变 - &gt;串

<Directory /home> <Limit ALL> AllowUser ftpadm DenyAll </Limit> <Limit STOR> AllowAll </Limit> </Directory> 关于堆内存更改的内容。

可变 - &gt; StringBuffer - StringBuilder String x = "value0ne";// adresse one x += "valueTwo"; //an other adresse {adresse two}

sb仍然在同一个地方,我希望这个评论有帮助