Can't understand how Java string literals are implemented

Eitanos30 :

I'm learning about the StringBuider class. I have read in this site and many other books that when the compiler meets a '+' operator of literal, it automatically uses StringBuilder append's method to concatenate them.

It seems a little bit problematic since a StringBuilder object will be created at run time but the String reference is supposed to get the address of the concatenate String object already at compilation time.

String s1 = "hello";  
String s2 ="bc"; 
int value = 22;

When the compiler "meets" this code:

String s = s1+s2+22;

it "changes" it to:

String s = new StringBuilder().append("hello").append("bc").append(22).toString();

Maybe I am misunderstanding something?

Andrew Tobilko :

15.18.1. String Concatenation Operator +

An implementation may choose to perform conversion and concatenation in one step to avoid creating and then discarding an intermediate String object. To increase the performance of repeated string concatenation, a Java compiler may use the StringBuffer class or a similar technique to reduce the number of intermediate String objects that are created by evaluation of an expression.

In your case,

String s1 = "hello";
String s2 ="bc";
int value = 22;

String r = s1 + s2 + value;

you will get

INVOKESPECIAL java/lang/StringBuilder.<init> ()V
ALOAD 1
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
ALOAD 2
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
ILOAD 3
INVOKEVIRTUAL java/lang/StringBuilder.append (I)Ljava/lang/StringBuilder;
INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;

While concatinating constant objects

String r = "hello" + "bc" + 22;

you will get

LDC "hellobc22"
ASTORE 2

When the compiler "meets" this code:

String s = s1+s2+22;

it "changes" it to:

String s = new StringBuilder().append("hello").append("bc").append(22).toString();

No. It may optimise it to

String s = new StringBuilder().append(s1).append(s2).append(value).toString();

but it can't replace s1 with "hello" because there is no guarantee the variable will keep referring to "hello". The variable is not final and thus open to reassignment.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=142042&siteId=1