vanik
vanik

Reputation: 33

Understanding java final variables

Can you please help me understand what happens if final variables are used in String concatenation? this is a certification question, so is not a question about how to compare string

String var1 = "varan";       
String an = "an";
final String an2 = "an";
System.out.println(var1 == ("var"+an));       
System.out.println(var1 == ("var"+an2));

Output :

false
true

Upvotes: 1

Views: 137

Answers (1)

Akash Thakare
Akash Thakare

Reputation: 23012

TL;DR

Because "var"+an is a different String Object newly created during runtime while "var"+an2 is compile time constant which is interned, and refer to the the same address where var1 is referencing.


Consider following example which is similar to your code.

public class TestString {

    public static void main(String[] args) {
        String stackOverflow = "stackOverflow";
        String overflow = "Overflow";

        final String overflowFinal = "Overflow";

        if (overflow == overflowFinal) {
            System.out.println("Both overflows are same!");
        }

        if (stackOverflow == ("stack" + overflow)) {
            System.out.println("Stack and overflow have same reference !");
        }

        if (stackOverflow == ("stack" + overflowFinal)) {
            System.out.println("Stack and overflowFinal have same reference !");
        }
    }

}

It will give following output :

Both overflows are same!
Stack and overflowFinal have same reference !

First of all kindly note that == compares the references of Strings and not the actual value.

JLS 15.18.1 states that,

The result of string concatenation is a reference to a String object that is the concatenation of the two operand strings. The characters of the left-hand operand precede the characters of the right-hand operand in the newly created string.

The String object is newly created (§12.5) unless the expression is a constant expression (§15.28).

So, from above statements we can say "stack" + overflow will be similar to String newString = new String("stackOverflow"); (Internally compiler will use StringBuilder to perform this concatenation).

For the final String JLS 4.12.4 states,

A variable of primitive type or type String, that is final and initialized with a compile-time constant expression (§15.28), is called a constant variable.

and so §15.28 says

A constant expression is an expression denoting a value of primitive type or a String that does not complete abruptly and is composed using only the following:

...

  • The additive operators + and -

...

Compile-time constant expressions of type String are always "interned" so as to share unique instances, using the method String.intern.

Now, above statements says if we declare String as a final, it ultimately becomes constant expression.

Note that String literals are also interned.

Interned String means if you are creating the String and one String with the same content(checked by .equals() method) which is already there in memory then it will not create new String but it will refer to the same memory location.

For example,

String a = "test";//String literals
String b = "test";
System.out.println("Is a & b interned ? :"+(a == b));

Output :

Is a & b interned ? : true

Upvotes: 2

Related Questions