Does the Java compiler efficiently handle embedded strings?

1.

static final String memFriendly = "Efficiently stored String"; System.out.println(memFriendly); 

2.

 System.out.println("Efficiently stored String"); 

Will the Java compiler handle both (1 and 2) of them in the same way?

FYI: Effectively, I mean memory usage at runtime, as well as code runtime. for example, can the first case take longer to load the stack of the memFriendly variable?

+4
source share
4 answers
 public static void main(String[] args) { System.out.println("Hello world!"); String hola = "Hola, mundo!"; System.out.println(hola); } 

Here is what javap shows as parsing for this code:

 0: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #22; //String Hello world! 5: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: ldc #30; //String Hola, mundo! 10: astore_1 11: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream; 14: aload_1 15: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 18: return 

It seems that the second line is saved, while the first is simply passed directly to the method.

This was built using the Eclipse compiler, which may explain the differences in my answer and McDowell's.

Refresh . Here are the results, if hola declared final (the result does not matter aload_1 , if I read this right, then this line is saved and as you might expect):

 0: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #22; //String Hello world! 5: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: ldc #30; //String Hola, mundo! 10: astore_1 11: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream; 14: ldc #30; //String Hola, mundo! 16: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 19: return 
+5
source

This is described in the Java Language Spec :

Each string literal is a reference (Section 4.3) to an instance (section 4.3.1, section 12.5) of the String class (section 4.3.3). string objects have a constant value. string literals - or, in a more general sense, strings that are constant expression values โ€‹โ€‹(ยง15.28) - are "interned", so how to exchange unique instances using the String.intern method.

You can also see for yourself using the javap tool.

For this code:

 System.out.println("Efficiently stored String"); final String memFriendly = "Efficiently stored String"; System.out.println(memFriendly); 

javap gives the following:

 0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3; //String Efficiently stored String 5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 11: ldc #3; //String Efficiently stored String 13: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 
+14
source

In this case, the compiler will process both.

Anytime String is determined at compile time, Java optimizes the storage of strings.

If a string is defined at runtime, Java is not able to do the same wholesale.

+2
source

The code you have is equivalent, because string literals are automatically interned by the compiler.

If you are really worried about String and will reuse the same strings over and over again, you should take a look at the intern method in the string class.

http://java.sun.com/javase/6/docs/api/java/lang/String.html#intern ()

-2
source

All Articles