2012-04-09 28 views
5

Người ta mong rằng mặc dù các chuỗi là bất biến, giá trị bình đẳng và tham chiếu-bình đẳng sẽ không giống nhau đối với các đối tượng java.lang.String trong Scala. Điều này có nghĩa là hai chuỗi giữ val s không được tham chiếu bằng nhau ngay cả khi các chuỗi của chúng giống nhau. Nhưng đây là những gì tôi nhận được trong phiên bản 2.9.1.final REPL:Tham chiếu bình đẳng cho java.lang.String trong Scala

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

scala> s1 eq s2 
res0: Boolean = true 

Bất kỳ ý tưởng nào tại sao kết quả không phải là false? Thử nghiệm tương tự với List("a") thay vì "a" hoạt động như mong đợi. Phương pháp eq được đánh dấu là cuối cùng trong AnyRef. Có bất kỳ phép thuật biên dịch nào được thực hiện riêng cho String hoặc java.lang.String không?

Trả lời

13

Vâng đó là phép thuật trình biên dịch. Cụ thể, nó được gọi là interning. Java làm điều đó là tốt, và nó chỉ đơn giản là vì lý do hiệu quả, chẳng hạn như sử dụng bộ nhớ và cho phép so sánh mà không so sánh mọi ký tự. Đây là số Wikipedia article on it. Bạn cũng có thể thực hiện Strings theo cách thủ công với phương thức intern().

4

Từ Java language specification:

Một chuỗi literal là một tham chiếu đến một thể hiện của lớp String (§4.3.1, §4.3.3).

Hơn nữa, một chuỗi ký tự luôn đề cập đến cùng một trường hợp của lớp String. Điều này là do các chuỗi ký tự - hoặc, nói chung, các chuỗi là các giá trị của các biểu thức không đổi (§15.28) - được "interned" để chia sẻ các cá thể duy nhất, sử dụng phương thức String.intern.

+0

Cảm ơn! Thật thú vị, khi tôi thay đổi ví dụ của tôi để bắt đầu với 'val s1 =" aa "; val s2 = "a" + "a" ', kết quả vẫn như cũ, mặc dù' "a" + "a" 'không phải là một biểu thức hằng số (là nó?). Vì vậy, có vẻ như Scala làm nhiều hơn một chút so với thông số Java nói. –

+3

'" a "+" a "' ** là ** một biểu thức liên tục, xem [Biểu thức liên tục] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html # jls-15.28) – fredoverflow

+1

Đặc tả Java cho các biểu thức liên tục dường như không giống hệt nhau đối với Scala. Ví dụ, bằng cách sử dụng một trong các ví dụ được đưa ra trên trang Constant Expressions đó, '" Số nguyên "+ java.lang.Long.MAX_VALUE +" là lớn mạnh. "' Không được thực hiện bởi scalac. –

Các vấn đề liên quan