我已经读过,在Java中,String类型的对象无法更改。但int和char变量可以。为什么?你能举个例子吗?
谢谢。 (我是一个新的-_-)
答案 0 :(得分:18)
正如bzabhi所说,字符串在Java中是不可变的。这意味着字符串对象永远不会改变。这并不意味着您无法更改字符串变量,只是您无法更改字符串的基础内存表示形式。举个例子:
String str = "Hello";
str += " World!";
在执行这些行之后,str将指向内存中的新字符串。原始的“Hello”字符串仍然存在于内存中,但很可能它不会存在很长时间。假设没有任何情有可原的情况,没有任何东西会指向原始字符串,因此它将被垃圾收集。
我想最好的方法就是说当示例的第2行执行时,内存中的新字符串是从原始字符串的串联和添加到其中的字符串创建的。然后将str变量(仅仅是对内存位置的引用)更改为指向刚刚创建的新变量。
我对这一点并不是特别了解,但是,据我所知,这就是所有“非原始”价值所发生的事情。在某些时候从Object派生的任何东西都遵循这些规则。原始值,例如int,bools,chars,float和double,允许更改内存中的实际值。所以,从这个:
int num = 5;
num += 2;
内存中的实际值发生变化。此代码示例不是创建新对象并更改引用,而只是更改num变量的内存值。
至于为什么这是真的,它只是Java制造商的设计决定。我相信有人会评论为什么会这样做,但这不是我所知道的。
答案 1 :(得分:9)
int和char也不能改变。与字符串一样,您可以将不同的值放入同一个变量中,但整数本身不会更改。 3将永远是3;你无法将其修改为4。
答案 2 :(得分:4)
String是一个不可变类型(其中的值不能更改)。所有原始类型(boolean,byte,char,short,int,long,float和double)都是如此。
int x;
String s;
x = 1;
x = 2;
s = "hello";
s = "world";
x++; // x = x + 1;
x--; // x = x - 1;
正如你所看到的,在任何情况下你都不能改变常数值(1,2,“你好”,“世界”),但你可以改变他们所指向的位置(如果你扭曲了一下你的思绪并说出一个int变量指向一个常量的int值)。
答案 3 :(得分:3)
我不确定是否可以(通过示例)显示字符串无法更改。但您可以通过阅读Javadoc for the String class的描述部分,然后阅读方法部分并注意到没有可以更改字符串的方法来确认这一点。
编辑:Strings被设计为在Java中不可变的原因有很多。最重要的原因是不可变字符串比可变字符串更容易正确使用。如果由于某种原因确实需要可变等效的String,可以使用StringBuilder(或StringBuffer)类。
答案 4 :(得分:2)
值得注意的是,由于字符串是不可变的,如果将它们传递给方法,则不能在方法内修改它们,然后在方法范围之外看到这些更改。
public void changeIt(String s) {
// I can't do anything to s here that changes the value
// original string object passed into this method
}
public void changeIt(SomeObject o) {
// if SomeObject is mutable, I can do things to it that will
// be visible outside of this method call
}
答案 5 :(得分:1)
这篇小文章可能比我能更好地解释它:http://www.jchq.net/tutorial/09_02Tut.htm
答案 6 :(得分:1)
字符串在java
中是不可变的。不过,您仍然可以为字符串附加或前置值。通过值,我的意思是原始数据类型或其他字符串。
但是,StringBuffer是可变的,即它可以在内存中更改(不必分配新的内存块),这使得它非常有效。另外,请考虑以下示例:
StringBuffer mystringbuffer = new StringBuffer(5000);
for (int i = 0; i<=1000; i++)
{
mystringbuffer.append ( 'Number ' + i + '\n');
}
System.out.print (mystringbuffer);
我们不是创建一千个字符串,而是创建一个可以扩展的单个对象(mystringbuffer
)。我们还可以设置一个推荐的起始大小(在这种情况下,5000字节),这意味着当一个新字符串被附加到缓冲区时,缓冲区不必一直请求内存。
虽然StringBuffer
不会在每种情况下提高效率,但如果您的应用程序使用长度增长的字符串,那么效率会很高。使用StringBuffer
s代码也可以更清晰,因为append方法使您不必使用长赋值语句。