0

The following code (from an interview) produces an output of false, but I believe it should be true.

public static void main(String[] args) {    
    String a = "hello";
    String b = a + "world";
    String c = "helloworld";
    System.out.println(b==c);
}

I thought that constant String expressions were interned, and a + "world" is a constant, so it should intern "hello world".

Can someone explain why the output is false?

Bohemian
  • 412,405
  • 93
  • 575
  • 722
vijay
  • 1
  • 2
  • yeah i know == gives you reference equality, .equal() to gives you content equality – vijay Jun 25 '18 at 16:06
  • 1
    @MihaiChelaru this question is about String interning **not** how to compare Strings. – Bohemian Jun 25 '18 at 16:57
  • @Bohemian Can you explain the answer? I have no idea, since it takes from the string literal pool, with the same hashcode value? – Ravindra Ranwala Jun 25 '18 at 17:00
  • 3
    *while it should be true*: why should it be true? You have two different String instances holding the same value (i.e. the same sequence of characters). So, if you understand how to compare strings, and what `==` does, why do you expect it to be true? – JB Nizet Jun 25 '18 at 17:03
  • @Bohemian How do you know? – shmosel Jun 25 '18 at 17:14
  • 1
    @shmosel because was an interview question, obviously around interning. I’ll edit the Q. – Bohemian Jun 25 '18 at 17:18

4 Answers4

2

Java interns all Strings that are compile time constants. However, only Strings declared by concatenating String literals are considered a compile time constant and so be interned.

This is because the compiler looks only at the line being compiled, so it has no idea if a if a is a constant or not. For example, a could be declared as:

String a = new Date().toString();

Hence, c is a different instance of String than b.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
0

When you do this,

String b=a+"world";

The compiler chooses a StringBuilder based concatenation of String objects like so,

StringBuilder sb = new StringBuilder(a);
sb.append("world"); 
String b = sb.toString();

This yields a different reference, hence returning false as in your case.

But if you use this,

String b="hello"+"world";

Then the compiler identifies it as a constant, and both the b and c variables reference the same literal in the constant pool. Hence it returns true.

Ravindra Ranwala
  • 20,744
  • 6
  • 45
  • 63
0

When you assign strings like in your example, a, b, and c are separate String objects. So when you compare them you get false because they are not the same object. == in Java does not do a character-by-character comparison of the string. That's what String.equals() is for.

This is a solid summary to read to understand: How do I compare strings in Java?

KT_
  • 978
  • 11
  • 26
  • The question is "Can someone explain the following code?" So I explained why his code behaves as it does. *His* question is not specifically about string interning, and it doesn't mention it at all. – KT_ Jun 25 '18 at 17:20
0

The code you are looking at does an equality comparison between two variables that point to two different string instances, which are diferent objects stored in different places in memory (among other things) and are therefore different even though the string they represent is the same.

To do a string comparison you would need to use

stringInstance.equals(anotherStringInstance)

If you did something like this

String a = "abcde";
String b = a;

Then you would get a == b to be true as both variables point to the same object.

ovimunt
  • 187
  • 1
  • 13