Before we move forward, let's discuss one of the most common errors beginning Java students encounter at this point in the course. We'll begin with an experiment. In the REPL, let's compare two strings:
> boolean stringComparison = "hello" == "hello";
boolean stringComparison = true
Here, we create a boolean value called stringComparison
and use the ==
equality operator to see if "hello"
is equal to "hello"
. Predictably, it returns true.
Now, let's do the same comparison, but this time, let's create our strings with constructors. Similar to the constructor we created for our own custom class, Java has built-in constructors for the built-in classes, like String
and Integer
:
> String firstString = new String("hello");
java.lang.String firstString = "hello"
> String secondString = new String("hello");
java.lang.String secondString = "hello"
> boolean secondStringComparison = firstString == secondString;
boolean secondStringComparison = false
Notice here that despite the two strings both containing the exact same content, "hello"
, this time the equality operator returns false! Even though it returned true the first time!
equals()
There are actually two primary manners of checking for equality in Java. The ==
operator, which we've already seen, and the equals()
method, which we have not.
The ==
operator evaluates whether two objects or primitives are equal based on the object's location in memory. You know how we can create an object in the REPL, execute a few more lines of code, then refer back to the first object and Java still remembers it?
This is because Java saves variable information in the computer's memory. When we execute the code seen in the example above, two variables named firstString
and secondString
are both saved into memory.
However, because firstString
and secondString
are two separate variables (even though they have the similar contents), they are stored in two separate places in the computer's memory. Remember, the ==
operator evaluates whether things are equal based on the objects' location in memory. So even though both firstString
and secondString
contain "hello"
, they're two separate variables, and therefore have two separate places in memory. If we attempt to compare them with ==
, it will return false
.
The following only returns true
because the two strings are never saved into memory. We define them right then and there, in the same statement we compare them:
> boolean stringComparison = "hello" == "hello";
boolean stringComparison = true
equals()
methodThe equals()
method, however, actually compares the values within two strings, not simply the object's location in memory.
Let's perform the exact same comparison we did earlier, using the equals()
method instead of ==
:
> String firstString = new String("hello");
java.lang.String firstString = "hello"
> String secondString = new String("hello");
java.lang.String secondString = "hello"
> boolean stringComparison = firstString.equals(secondString);
boolean stringComparison = true
And look! It correctly returns true
this time around!
Moving forward, always, always, always use equals()
to compare Strings. Especially strings that belong to objects. Even though we know ==
works correctly in limited instances, .equals()
will always work.
The ==
operator evaluates whether two objects or primitives are true based on the object's location in memory.
The equals()
method, however, actually compares values within strings.
This in mind, do not use ==
to compare strings. If two separate strings are created, even if the strings contain the same exact content they will be saved in two separate places in the computer's memory. ==
will then return false
when comparing them, because it only considers the objects' location in memory.
Moving forward, always, always, always use equals()
to compare Strings. Especially strings that belong to objects. Even though we know ==
works correctly in limited instances, .equals()
will always work.
==
incorrectly returning false
:
> String firstString = new String("hello");
java.lang.String firstString = "hello"
> String secondString = new String("hello");
java.lang.String secondString = "hello"
> boolean secondStringComparison = firstString == secondString;
boolean secondStringComparison = false
equals()
correctly returning true
:
> String firstString = new String("hello");
java.lang.String firstString = "hello"
> String secondString = new String("hello");
java.lang.String secondString = "hello"
> boolean stringComparison = firstString.equals(secondString);
boolean stringComparison = true