Java 如果创建了新实例,字符串是否会失去可变性

Java 如果创建了新实例,字符串是否会失去可变性,java,string,jvm,Java,String,Jvm,我知道字符串本质上是不变的。但我有一个问题 String a = new String("abc"); 如果我们像上面那样创建一个字符串而不是一个文本,那么它不是作为一个新对象创建的吗?请澄清。谢谢。不,没有。无论java字符串是如何创建的,它总是不可变的 实际上,使用new创建字符串是多余的,在99%的情况下应该避免(除非您正在进行一些微基准测试) 不可变意味着实例一旦创建就不能修改。当您查看String的所有方法时,没有一个方法实际修改传递给它的原始字符串。它们要么返回相同的字符串,要么创

我知道字符串本质上是不变的。但我有一个问题

String a = new String("abc");
如果我们像上面那样创建一个字符串而不是一个文本,那么它不是作为一个新对象创建的吗?请澄清。谢谢。

不,没有。无论java字符串是如何创建的,它总是不可变的

实际上,使用
new
创建字符串是多余的,在99%的情况下应该避免(除非您正在进行一些微基准测试)

不可变意味着实例一旦创建就不能修改。当您查看String的所有方法时,没有一个方法实际修改传递给它的原始字符串。它们要么返回相同的字符串,要么创建一个新字符串。

否。它不会。无论java字符串是如何创建的,它总是不可变的

实际上,使用
new
创建字符串是多余的,在99%的情况下应该避免(除非您正在进行一些微基准测试)


不可变意味着实例一旦创建就不能修改。当您查看String的所有方法时,没有一个方法实际修改传递给它的原始字符串。它们要么返回相同的字符串,要么创建一个新字符串。

您的
字符串是不可变的,因为字符串总是不可变的(视图)

String a=“abc”之间的差异
字符串a=新字符串(“abc”)不是易变性,是字符串池的使用。当你这样做的时候

String a = "abc";
String a = new String("abc");
您正在使用Java字符串池(请参阅)

当你这么做的时候

String a = "abc";
String a = new String("abc");
您没有使用字符串池

字符串池存储不同的字符串实例,这就是为什么使用该池创建两个不同的对象时,引用是相同的

无论如何,在这两种情况下,都不能更改字符串实例的状态(
String
是不可变的)


使用
new
创建字符串几乎总是可以避免的。

您的
字符串是不可变的,因为字符串总是不可变的(视图)

String a=“abc”之间的差异
字符串a=新字符串(“abc”)不是易变性,是字符串池的使用。当你这样做的时候

String a = "abc";
String a = new String("abc");
您正在使用Java字符串池(请参阅)

当你这么做的时候

String a = "abc";
String a = new String("abc");
您没有使用字符串池

字符串池存储不同的字符串实例,这就是为什么使用该池创建两个不同的对象时,引用是相同的

无论如何,在这两种情况下,都不能更改字符串实例的状态(
String
是不可变的)


使用
new
创建字符串几乎总是可以避免的。

这是一个可变对象:

class Person {
  private name;
  Person(String name) { this.name = name; }
  void setName(String name) { this.name = name; }
}
因为您可以在创建后更改其状态:

Person john = new Person("John");
john.setName("Fred"); //oops, John's name is not John any more...
另一方面,一旦您创建了一个字符串,就没有任何方法允许您更改该字符串的值

String john = "John";
john.setValue("Fred"); //No, that's not possible...

当然,这不会阻止您创建具有类似或不同值的新字符串。

这是一个可变对象:

class Person {
  private name;
  Person(String name) { this.name = name; }
  void setName(String name) { this.name = name; }
}
因为您可以在创建后更改其状态:

Person john = new Person("John");
john.setName("Fred"); //oops, John's name is not John any more...
另一方面,一旦您创建了一个字符串,就没有任何方法允许您更改该字符串的值

String john = "John";
john.setValue("Fred"); //No, that's not possible...

当然,这并不妨碍您创建具有相似或不同值的新字符串。

您似乎误解了不变性的概念。Java中的字符串文字只是字符串对象的有用表示形式,设计上是不可变的。“不可变”并不意味着“硬编码”。你似乎误解了不可变的概念。Java中的字符串文字只是字符串对象的有用表示形式,设计上是不可变的。“不可变”并不意味着“硬编码”。但如果我们使用相同值的
new
(比如“abc”)创建两个不同的字符串对象,那么这两个字符串对象都指向两个不同的内存位置,它们只是作为普通对象。那么它们怎么可能是不变的呢。谢谢。@Ramson字符串是“不可变的”,因为无法(没有方法)修改指针指向的字符串对象内的数据。涉及指针的事实无关紧要。@Ramson字符串是不可变的,但它们不强制“唯一性”:您可以创建任意多个等于“abc”的字符串。@Ramson-不可变意味着实例的值不能更改。不变性是在实例级别定义的。仅仅因为字符串是普通对象,并不意味着它们应该是可变的。包装类是不可变的。我不明白你在这里想说什么@拉姆森:-)这是一个旨在提高性能的设计决策。有许多低级优化利用了不变性的特性。最简单的是,删除同步。不可变实例是线程安全的。另外,字符串常量池中有可以重用的字符串,这样可以减少创建时间并提高重用性。很多东西。但是如果我们使用具有相同值的
new
创建两个不同的字符串对象(比如“abc”),那么这两个字符串对象都指向两个不同的内存位置,它们只是作为普通对象。那么它们怎么可能是不变的呢。谢谢。@Ramson字符串是“不可变的”,因为无法(没有方法)修改指针指向的字符串对象内的数据。涉及指针的事实无关紧要。@Ramson字符串是不可变的,但它们不强制“唯一性”:您可以创建任意多个等于“abc”的字符串。@Ramson-不可变意味着实例的值不能更改。不变性是在实例级别定义的。仅仅因为字符串是普通对象,并不意味着它们应该是可变的。包装类是不可变的。我不明白你在这里想说什么@拉姆森:-)这是一个旨在提高性能的设计决策。有许多低级优化