The Spaghetti Refactory Established 2015

Hidden pitfalls of comparing strings in Java

I’ve been learning some Java to get into Android coding. It is certainly more verbose compared to Ruby. As a simple example (which will lead me into the topic at hand), let’s say I have a variable called word with the string “widget” stored. If I want just the first letter of the word:

# Ruby
word[0]

// Java
word.substring(0,1);

What’s more, the Ruby method above returns a normal String object that can be acted on like any other string. So, if in Ruby I wanted to check if the first letter in the word was “w”:

# Ruby
word[0] == "w"

Based on that, I figured I could do something similar in Java:

// Java
word.substring(0,1) == "w";

Fail! And it’s the worst kind of fail - it doesn’t even give an error! It just returns false, even though I know that word.substring(0,1) will return “w”.
When I tried a few combinations of things in javarepl, I got some interesting results:

String letter = word.substring(0,1);
letter == "w";
// ERROR: illegal start of expression
// = "w";
// ^

and

"w" == "w"
// java.lang.Boolean res9 = true

but

word.substring(0,1) == "w";
// java.lang.Boolean res10 = false

Really strange. My guess is that in the first example, it’s trying to assign “w” even though I’m attempting to use the equality operator. But if that’s true, I have no idea why it’s doing what it’s doing in the other two.

Just for posterity, the way to get the third example to return true like it should is to use the equals method:

word.substring(0,1).equals("w");
// java.lang.Boolean res11 = true