java中可变字符串和不可变字符串的区别是什么

java中可变字符串和不可变字符串的区别是什么,java,string,immutability,mutable,stringbuffer,Java,String,Immutability,Mutable,Stringbuffer,据我所知 可以更改可变字符串,并且 无法更改不可变字符串 这里我想像这样改变字符串的值 String str="Good"; str=str+" Morning"; 另一种方式是 StringBuffer str= new StringBuffer("Good"); str.append(" Morning"); 在这两种情况下,我都试图更改str的值。谁能告诉我,这两种情况的区别是什么,并让我清楚地了解可变对象和不可变对象。当你说str时,你应该小心你的意思: 您是指变量str 还是说s

据我所知

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

这里我想像这样改变字符串的值

String str="Good";
str=str+" Morning";
另一种方式是

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

在这两种情况下,我都试图更改
str
的值。谁能告诉我,这两种情况的区别是什么,并让我清楚地了解可变对象和不可变对象。

当你说
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);
}

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

Java
String
s是不可变的

在第一个示例中,您将引用更改为
字符串
,从而将另外两个
字符串
组合的值赋给它:
str+“Morning”

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

java中可变字符串和不可变字符串的区别是什么

不可变存在,可变不存在。

案例1: 在上面的代码中,您创建了3个
String
对象

  • “好”它进入了弦池
  • “早上好”,它也会进入弦乐池
  • 通过连接“Good”和“Morning”创建的“Good Morning”。这家伙真是疯了 注意:字符串总是不可变的。没有可更改字符串之类的东西
    str
    只是一个最终指向“早上好”的参考。实际上,您不是在处理
    1
    对象。您有
    3
    distinct
    String
    对象


    案例2:
    StringBuffer
    包含一个字符数组。它与
    字符串不同。
    
    上面的代码将字符添加到现有数组中。实际上,
    StringBuffer
    是可变的,它的
    String
    表示不是可变的。

    为了更好地理解,我用输出注释修改了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中,更改的值作为全局变量受影响

    因此字符串是不可变的,而StringBuffer是可变的

    简单地说,无论您将什么更改为字符串对象,都只会通过转到字符串池来影响该函数。但没有改变…

    • :-可更改
    • :-不可更改

    Java中的字符串是不可变的。然而,在编程环境中可变意味着什么是第一个问题。考虑以下类,

    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 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 !";
    // ...
    
    所以

  • str1
    str2
    是在字符串常量池中创建的字符串文本
  • str3
    str4
    str5
    是放置在堆内存中的字符串对象
  • str1=“你好!”
    在字符串常量池中创建
    “Hi!”
    ,它与前面引用的
    str1
    完全不同
  • 这里我们创建字符串文本或字符串对象。两者都是不同的,我建议你们阅读下面的帖子来了解更多

    在任何字符串声明中,有一点是常见的,即它不会修改,但会被创建或转移到另一个

    字符串是如何变得不可变的

    这是一种不变的行为,意味着一旦赋值,就不能以任何其他方式更新。String类在内部保存字符数组中的数据。此外,类被创建为不可变的。看看这个定义不可变类的策略

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

    为什么StringBuffer是可变的


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

    可变变量是指其值可能会就地更改的变量,而在不可变变量中,值不会就地更改。修改不可变变量将重新生成相同的变量。

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

    不可变的->字符串

    Dimension d = new Dimension(); d.setSize(10, 20);// Dimension changed d.setSize(10, 200);// Dimension changed d.setSize(100, 200);// Dimension changed
    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 !";
    // ...
    
    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 str="java";
    
    String str = new String("java");
    
    char[] helloArray = { 'h', 'e', 'l', 'l', 'o', '.' };
    
    String helloString = new String(helloArray);   
    
    String s="kumar";
    
    System.out.println(s.hashCode());
    
    System.out.println("value "+s);
    
    String s1="kumar";   // what you think is this line, takes new location in the memory ??? 
    
    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 ???
    
    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());
    }
    }
    
    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());
    
    
        }
    }