This question is certainly undecidable, yet you can find out how a certain combination of java compiler and JVM does it.
As far as I can see, nothing could stop one from writing a java compiler that, when it sees a string constant, emits byte code to create that string in the heap in some way as long as the rules stated in the JLS concerning string literals are still maintained. For example, String.intern
could maintain a global Map, and the compiler could compile a String literal like follows:
create a char array of the desired size
put character at index 0
put character at index 1
...
put character at index (length-1)
construct the actual string object
pass the String just created to String.intern and leave result on the stack
Actually, one could have a pre-processor changing all string constants to
(extra.HeapString.createString(new char[] { ... }))
and have createString
create a String instance in such a way that the rules for String literals hold. And you couldn't write a program that could detect if it was compiled from the original source or from the preprocessed one (except through reflection on extra.HeapString
).