就这两个概念<<think in java>>的第二章里面已经讲的很清楚了,现在手头没书,就只有大概的说说我对他们的理解了....可能会有偏差吧.:-) 首先我纠正一下我的错误了."1"不应该放在静态存储空间,而应该放在常量存储空间里面了.真是不好意思.静态存储空间:实际上这是存在于RAM的,但是他是在一个fixed(固定)的位置.一般说来,用static关键字定义的都放在这里,在整个运行过程都是存在的.常量存储空间:存放在代码中直接写的常量的值,类似于"1","123",等等(我认为),存放在ROM里面.(不太确定)堆:当然不用说了,都是存放的new出来的对象的.也就是说,在运行的其间为了你的对象的生存而开辟出来的存储空间.
Never use "==" to compare strings. This only determines whether or not the strings are stored in the same location. Use equalTo() or compareTo() to test string equality.So why String a = "1" and String b = "1" share the same location? Because every time you create a new string, the JVM will map the string to a specific location according to the string's value. The values of String a and String b are "1", so they were mapped to the same location. In this case, using a==b will return true.But if you change the string's value, JVM will map the changed string to another location because the string's value has been changed. There is a hashtable-relationship between the string's value and string's location. So in this case == will never work.
回复 doodoofish(嘟嘟鱼) 你有几个地方说得不太严谨甚至错误, 批驳如下: 1.并不是每次创建一个String变量的时候,JVM都会搜索比较一下值,然后决定是否返回相同的reference,事实上,当用"="创建时,JVM确实会如此去做,但是当你用new去创建时,JVM根本就不会去搜索比较,它肯定返回不同的reference,而不管其值是否相同.这就是为什么尽量不要用String s = new String("a")去创建一个String变量,而用String s = "a"的原因. 2.String的值是不可改变的,你所改变的仅仅是reference. 3.String的值和位置之间并不存在hashtable-relationship,String的哈希值只与其字符串有关,而与位置无关.
2.String的值是不可改变的,你所改变的仅仅是reference. 我是沒說清楚﹐謝謝指教。應該說"試圖對String進行改變值的操作後......"3.String的值和位置之间并不存在hashtable-relationship,String的哈希值只与其字符串有关,而与位置无关. 那麼說String a = "dog"和String b = "god"公享一個地址?
另外﹐String是immutable(不可變的)的。從表層來看﹐你可以改變一個String的值﹐比如: a = "abc" + "d"; 但實際上﹐這時候的a的location已經發生了變化﹐也就是說這時候的a是個新生成的String﹐而原來那個a的location裡仍然佔用了內存。如果編輯String的操作很多就很費資源和時間﹐因為我們在反復生成新的String﹐所以我們需要StringBuffer這個類來幫我們完成編輯String的任務。
to: msybox(南方人) 非常正确,可以参见嘟嘟鱼的回复,JVM确实是这样做的.to: doodoofish(嘟嘟鱼) 再次强调一下哈希值与地址无关性: String a = "dog"和String b = "god"当然不会共享一个地址,它们的哈希值也不相同. 如果 a==b为true, 则a,b的哈希值必然相同,如果 a==b为false, a.equals(b)为true,则a,b的哈希值也相同,如果a.equals(b)为false则a,b的哈希值可能不同,也可能相同.这就是所谓的"哈希冲突",当然好的算法应该尽可能保证在a.equals(b)为false时,a和b的哈希值不同,但无法绝对避免.现贴出String.hashCode()算法,大家可以想一想什么情况下会产生"哈希冲突"? public int hashCode() { int h = hash; if (h == 0) { int off = offset; char val[] = value; int len = count; for (int i = 0; i < len; i++) h = 31*h + val[off++]; hash = h; } return h; }
JAVA里的String类型比较特殊,用equals或者==都一样,
只是习惯上都用equals更符合面向对象的思想.
如:
String strTemp1="1";
String strTemp2="1";
strTemp1==strTemp2与strTemp1.equals(strTemp2)的boolean值是相同的.但楼主的是ls_temp.substring(1,2) == "1".
不知道大家有没注意到String的操作substring(),
经过测试发现substring得到的串与直接赋串值的变量的串是不"=="的,
但是equals的,或者这就是对象的特别之处.即:
==是比较地址的,equals是比较值的.
请指教.
当你用
String strTemp1="1";
String strTemp2="1";
事实上strTemp1和strTemp2的地址是相同的(节约了空间),于是strTemp1==strTemp2和strTemp1.equals(strTemp2)返回都是true.
而当你用了substring()操作时,java会重新开新的内存地址,所以有可能会有
strTemp1.equals(strTemp2)为true,而strTemp1==strTemp2为false
"1"作为一个常量,是保存在静态存储空间上的.所以实际上strTemp1和strTemp2都是一个句柄,指向这个空间的.
而用了substring后,其存储是建立在堆上的.
首先我纠正一下我的错误了."1"不应该放在静态存储空间,而应该放在常量存储空间里面了.真是不好意思.静态存储空间:实际上这是存在于RAM的,但是他是在一个fixed(固定)的位置.一般说来,用static关键字定义的都放在这里,在整个运行过程都是存在的.常量存储空间:存放在代码中直接写的常量的值,类似于"1","123",等等(我认为),存放在ROM里面.(不太确定)堆:当然不用说了,都是存放的new出来的对象的.也就是说,在运行的其间为了你的对象的生存而开辟出来的存储空间.
你有几个地方说得不太严谨甚至错误, 批驳如下:
1.并不是每次创建一个String变量的时候,JVM都会搜索比较一下值,然后决定是否返回相同的reference,事实上,当用"="创建时,JVM确实会如此去做,但是当你用new去创建时,JVM根本就不会去搜索比较,它肯定返回不同的reference,而不管其值是否相同.这就是为什么尽量不要用String s = new String("a")去创建一个String变量,而用String s = "a"的原因.
2.String的值是不可改变的,你所改变的仅仅是reference.
3.String的值和位置之间并不存在hashtable-relationship,String的哈希值只与其字符串有关,而与位置无关.
String的值是不会变的.类似于这种类可以称之为常量类.还有一些常量类好象还有:BigDecimal,BigInteger.
我是沒說清楚﹐謝謝指教。應該說"試圖對String進行改變值的操作後......"3.String的值和位置之间并不存在hashtable-relationship,String的哈希值只与其字符串有关,而与位置无关.
那麼說String a = "dog"和String b = "god"公享一個地址?
a = "abc" + "d";
但實際上﹐這時候的a的location已經發生了變化﹐也就是說這時候的a是個新生成的String﹐而原來那個a的location裡仍然佔用了內存。如果編輯String的操作很多就很費資源和時間﹐因為我們在反復生成新的String﹐所以我們需要StringBuffer這個類來幫我們完成編輯String的任務。
String strTemp2="1";
事实上strTemp1和strTemp2的地址是相同的(节约了空间),于是strTemp1==strTemp2和strTemp1.equals(strTemp2)返回都是true.
如果说strTemp1和strTemp2的地址相同,当我执行以下语句时
strTemp2 = "2";
java虚拟机会怎样处理?在一个新地址的内存空间中产生“2”这个字符串,然后改写strTemp2中存储的地址?
非常正确,可以参见嘟嘟鱼的回复,JVM确实是这样做的.to: doodoofish(嘟嘟鱼)
再次强调一下哈希值与地址无关性:
String a = "dog"和String b = "god"当然不会共享一个地址,它们的哈希值也不相同.
如果 a==b为true, 则a,b的哈希值必然相同,如果 a==b为false, a.equals(b)为true,则a,b的哈希值也相同,如果a.equals(b)为false则a,b的哈希值可能不同,也可能相同.这就是所谓的"哈希冲突",当然好的算法应该尽可能保证在a.equals(b)为false时,a和b的哈希值不同,但无法绝对避免.现贴出String.hashCode()算法,大家可以想一想什么情况下会产生"哈希冲突"?
public int hashCode() {
int h = hash;
if (h == 0) {
int off = offset;
char val[] = value;
int len = count; for (int i = 0; i < len; i++)
h = 31*h + val[off++];
hash = h;
}
return h;
}