2012-04-09 63 views
5

人們會期望即使字符串不可變,對於Scala中的java.lang.String對象,值相等和引用相等也不會相同。這意味着即使兩個字符串相同,兩個字符串保持val也不應該引用相等。但這裏是我得到的2.9.1.final REPL:Scala中的java.lang.String的引用相等

scala> val s1 = "a"; val s2 = "a" 
s1: java.lang.String = a 
s2: java.lang.String = a 

scala> s1 eq s2 
res0: Boolean = true 

任何想法,爲什麼結果還是不行false?與List("a")相同的實驗而不是"a"按預期工作。 eq方法在AnyRef中標記爲final。是否有專門爲Stringjava.lang.String完成的編譯器魔法?

回答

13

是的,它是編譯器的魔力。具體來說,它被稱爲內部。 Java也是如此,它僅僅是出於效率的原因,比如內存使用和允許比較而不用比較每個字符。這是一個Wikipedia article on it。您也可以使用intern()方法手動實習字符串。

4

Java language specification

字符串文字是String類(第4.3.1節,§4.3.3)的實例的引用。

此外,字符串文字總是指類String的相同實例。這是因爲使用方法String.intern將字符串文字(或更一般地說是常量表達式的值(§15.28))的字符串「interned」以便共享唯一實例。

+0

謝謝!有趣的是,當我改變我的例子開始'val s1 =「aa」; val s2 =「a」+「a」',即使'「a」+「a」不是一個常量表達式(是嗎?),結果仍然是一樣的。所以看起來Scala比Java規範所說的要多一點。 – 2012-04-09 11:21:53

+3

'「a」+「a」**是一個常量表達式,請參見[常量表達式](http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html #jls-15.28) – fredoverflow 2012-04-09 11:29:24

+1

常量表達式的Java規範對於Scala來說看起來並不完全一樣。例如,使用該常量表達式頁面上給出的示例之一,「」整數「+ java.lang.Long.MAX_VALUE +」非常大。「不是由scalac實現的。 – 2012-04-09 15:44:18

相關問題