Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does this Java code snippet work? (String pool and reflection) [duplicate]

Java string pool coupled with reflection can produce some unimaginable result in Java:

import java.lang.reflect.Field;  class MessingWithString {     public static void main (String[] args) {         String str = "Mario";         toLuigi(str);         System.out.println(str + " " + "Mario");     }      public static void toLuigi(String original) {         try {             Field stringValue = String.class.getDeclaredField("value");             stringValue.setAccessible(true);             stringValue.set(original, "Luigi".toCharArray());         } catch (Exception ex) {             // Ignore exceptions         }     } } 

Above code will print:

"Luigi Luigi"  

What happened to Mario?

like image 361
macrog Avatar asked Sep 17 '15 06:09

macrog


People also ask

What is the use of string pool in Java?

String Pool is a storage area in Java heap. String allocation, like all object allocation, proves to be a costly affair in both the cases of time and memory. The JVM performs some steps while initializing string literals to increase performance and decrease memory overhead.

What is string and string pool in Java?

All Strings are stored in the String Pool (or String Intern Pool) that is allocated in the Java heap. String pool is an implementation of the String Interring Concept. String Interning is a method that stores only a copy of each distinct string literal. The distinct values are stored in the String pool.

Can we have duplicate values in string constant pool?

Although both reference variable s3 and s4 point to the String objects with the same value Hello but as these objects are creating with the new keyword, hence, these objects are stored in normal heap memory where the String objects with duplicate values can be stored.

What makes Java more memory efficient string or string pool?

To make the java more memory efficient the concept of string literal is used. By the use of 'new' keyword, the JVM will create a new string object in the normal heap area even if the same string object present in the string pool.


2 Answers

What happened to Mario ??

You changed it, basically. Yes, with reflection you can violate the immutability of strings... and due to string interning, that means any use of "Mario" (other than in a larger string constant expression, which would have been resolved at compile-time) will end up as "Luigi" in the rest of the program.

This kinds of thing is why reflection requires security permissions...

Note that the expression str + " " + "Mario" does not perform any compile-time concatenation, due to the left-associativity of +. It's effectively (str + " ") + "Mario", which is why you still see Luigi Luigi. If you change the code to:

System.out.println(str + (" " + "Mario")); 

... then you'll see Luigi Mario as the compiler will have interned " Mario" to a different string to "Mario".

like image 50
Jon Skeet Avatar answered Sep 23 '22 08:09

Jon Skeet


It was set to Luigi. Strings in Java are immutable; thus, the compiler can interpret all mentions of "Mario" as references to the same String constant pool item (roughly, "memory location"). You used reflection to change that item; so all "Mario" in your code are now as if you wrote "Luigi".

like image 32
Amadan Avatar answered Sep 26 '22 08:09

Amadan