7

What is the difference between val a=new String("Hello") and val a="Hello"

Example:

val a="Hello"
val b="Hello"
a eq b
res:Boolean=True

Similarly:

val a=new String("Hello")
val b=new string("Hello")
a eq b
res:Bolean=False
Chirlo
  • 5,989
  • 1
  • 29
  • 45
AAA
  • 354
  • 1
  • 3
  • 14

2 Answers2

16

eq compares memory references.

String literals are put in a string constants pool, so in the first example they share the same memory reference. This is a behavior that comes from Java (scala.String is built on top of java.lang.String).

In the second example you're allocating two instances at runtime so when you compare them they're are at different memory locations.

This is exactly the same as Java, so you can refer to this answer for more information: What is the difference between "text" and new String("text")?

Now, if you want to compare their values (as opposed to their memory references), you can use == (or equals) in Scala.

Example:

val a = new String("Hello")
val b = new String("Hello")
a eq b // false
a == b // true
a equals b // true

This is different than Java, where == is an operator that behaves like eq in Scala.

Also note that == and equals are slightly different in the way the deal with null values (== is generally advised). More on the subject: Whats the difference between == and .equals in Scala?

Community
  • 1
  • 1
Gabriele Petronella
  • 106,943
  • 21
  • 217
  • 235
  • "String literals are put in a string constants pool" – can you provide any source for that? I tried to find a reference in the Scala Language Specification, but there is nothing in the section on [`String`](http://scala-lang.org/files/archive/spec/2.11/01-lexical-syntax.html#string-literals)s. There *is* an explicit reference to pooling in the section on [`Symbol`](http://scala-lang.org/files/archive/spec/2.11/01-lexical-syntax.html#symbol-literals)s ("The `apply` method of `Symbol`'s companion object caches weak references to `Symbol`s, thus ensuring that identical symbol literals are … – Jörg W Mittag Aug 16 '16 at 14:07
  • … equivalent with respect to reference equality."), so the fact that something similar is *not* documented for `String`s seems to be a *deliberate* omission and not a simple oversight, or, in other words, the Scala designers do *not* guarantee `String` pooling the same way they guarantee for `Symbol`s. – Jörg W Mittag Aug 16 '16 at 14:07
  • It's not in the Scala Language Specification because it is Java's behavior from [JLS §3.10.5](https://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.10.5) whose behavior is implemented in [JVM spec 5.1](https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html). The term commonly used is string "interning." See my answer below. – Scott Shipp Aug 16 '16 at 16:22
  • Thanks for the link @ScottShipp. Indeed this is a behavior that comes from Java. Scala Strings are build on top of java.lang.String. – Gabriele Petronella Aug 16 '16 at 16:48
1

First of all eq (and its opposite ne) are used for what is called reference equality.

The behavior you observed is the result of what's technically known as string interning and is the inherited behavior from Java. Scala makes use of java.util.String under the hood. You can observe this in the REPL:

scala> val s = "Hello World!"
s: String = Hello World!

scala> s.isInstanceOf[java.lang.String]
res1: Boolean = true

You can see a general explanation of eq, ne, and == here.

To learn about JVM string interning see this Wikipedia article.

Scott Shipp
  • 2,241
  • 1
  • 13
  • 20