9

What are the mechanics behind Java automatically interpreting string literals as String objects, since there are no overloaded operators and there is no default support for low-level string buffers (not including the high level StringBuffer)? Is this a language or virtual machine context?

3 Answers 3

7

It's a little of both.

The JVM has byte codes for loading string literals onto the runtime stack, and these opcodes are specified in the JVM spec to work by pushing an appropriately-constructed String object onto the stack whose contents are equal to some string literal specified in the class file. There is no specification for how this is done other than that the String object must be interned, meaning that the transformation is implementation-specific.

At the language level, the compiler can treat any String literal it sees as a complete String object for the purposes of type checking, and can then just write out the literal and the appropriate bytecodes into the class file.

Sign up to request clarification or add additional context in comments.

9 Comments

Is there any way to write programs in Java byte code (akin to some kind of assembly language) as a learning exercise?
Yes there are java assemblers available... Jasmin is one. Also you can use the BCEF to dynamically create classes from bytecode at runtime, or modifty classes
@Aaron: I believe you mean BCEL; but that's old-school. The modern way to create bytecode on the fly is by using ASM.
Is there any way to invoke a class loader on a memory buffer (ie a class you created from bytecode at runtime)? *you don't need to be specific, the thought of it is just too interesting to me now
Yes, definitely... I think ClassLoader has a method called defineClass that does this. Isn't Java awesome?
|
3

Java actually does have a few overloaded operators. For example, + can be applied to String objects as well as to int, float, and other numerical types. In each case, the return type is defined by the type of the expression on each side of the +. However, all overloaded operators are predefined in the language; programmers have no mechanism in the language to define any others. See the language specification for details.

3 Comments

Wasn't me, sorry. I got downvoted for suggesting that someone pause and resume a thread rather than destroying it and making new instances of the thread, and nobody came up to explain why.
@TurtleToes: I wrote a comment explaining why your answer was terrible (but I wasn't the one who downvoted you; maybe they'll show themself, or not).
Yeah I got a chuckle out of that one, thanks :p but at least my reasoning was in the right place; perhaps not for the specific context, but in general terms
0

Basically the compiler rewrites your code.

String x = "Some String";

For concatenation, it is just syntactic sugar for StringBuffer append method, ie this:

z += " with some more in it";

is compiled as:

z = new StringBuffer(z).append(" with some more in it").toString();

Now for a single concat this is an object created and 2 method calls, so if you are building a very long string inside a loop, it is FAR more efficient to write:

StringBuilder buf = new StringBuilder(); // Not synchronized so quicker than StringBuffer
while ( condition is true )
    buf.append(...);
String z = buf.toString();

rather than:

String z = "";
while (condition is true)
   z += "...";

Edit: removed wrong code example...

7 Comments

No, "I am a string" is not new String("I am a string"); if it were so, you'd get infinitely recursive calls to the String constructor!
A minor detail - all string literals are interned, so a string literal is not quite the same thing as making a new String. It will hand back the String instance shared by all string literals with the same value.
@templatetypedef: Actually, it's a significant detail. I sometimes write code that exploits that property: e.g., if I know I'm comparing two variables that I know are string literals or otherwise interned, I use identity comparison.
@Chris : could you provide an example illustrating that?
@bguiz: One example is where we (at work) had to intern all the setting names (because otherwise, it made our heap usage explode for no good reason). Once that decision was made, all the setting names could be compared using identity comparison. (The interning and comparison are well hidden behind private methods, so that calling code doesn't have to concern itself with such implementation details.)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.