Albus Dumbledore
Albus Dumbledore

Reputation: 12616

Time of Strings Creation in Java

I am writing an app for J2ME devices and pretty much care about unnecessary String creation. As working with Strings is built-in, i.e. it is not necessary to create them explicitly, I am not sure if I understand it right.

For instance returning a String (just by using the double quotes) creates the string when it is being returned, i.e. if I have several return statements returning different Strings, only one of the would be created. Is that right?

Also when using Strings for printing messages with Exceptions, these Strings never get created, if the Exception doesn't get thrown, right?

Sorry to bother you with such a newbie question.

Upvotes: 8

Views: 286

Answers (6)

sky
sky

Reputation: 447

The main concept here is that the heap allocation(what you say creation) for any String or in more general terms for any object doesn't take place until your logic-flow makes the interpreter executes that line of compiled code.

Upvotes: 0

Stephen C
Stephen C

Reputation: 719641

The answer is a bit more complicated than some of the other answers suggest.

  • The String value that corresponds to a String literal in your source code gets created once, when the class is loaded. Furthermore, these Strings are automatically "interned", which means that if the same literal appears at more than one place in any class, only one copy of the String will be kept. (Any other copies, if they were created will get garbage collected.)

  • When the application calls new String(...), when it evaluates a String concatenation expression (i.e. the + operator), or when it calls one of the many library methods that create Strings under the hood, a new String will be created.

So to answer your questions:

1 - The following will not actually create a String at all. Rather it will return a String that was created when the class was loaded:

        return "some string";

2 - The following will create two Strings. First it will call someObject.toString(), then it will concatenate that with the literal to give another String.

        return "The answer is :" + someObject;

3 - The following will not create a String; see 1.

        throw new Exception("Some message");

4 - The following will create two Strings when it is executed; see 2.

        throw new Exception(someObject + "is wrong");

(Actually, 3 and 4 gloss over the fact that creating an exception causes details of the current thread's call stack to be captured, and those details include a method name, class name and file name for each frame. It is not specified when the Strings that represent these things actually get created, or whether they are interned. So it is possible that the act of creating an Exception object triggers creation of a number of Strings.)

Upvotes: 2

Andreas Dolk
Andreas Dolk

Reputation: 114837

Yes. If an expression that creates an instance either by invoking a constructor or if (for Strings) evaluating a literal is not executed, then nothing is created.

And furtheron, compilers do some optimization. String objects based on String literals will be created only once and interned afterwards. like here:

public String getHello() {
  return "Hello";  
}

public void test() {
  String s = getHello();  // String object created
  String t = getHello();  // no new String object created
}


The JVMS has a different 'opinion':

A new class instance may be implicitly created in the following situations:

  • Loading of a class or interface that contains a String literal may create a new String object (§2.4.8) to represent that literal. This may not occur if the a String object has already been created to represent a previous occurrence of that literal, or if the String.intern method has been invoked on a String object representing the same string as the literal.

So the above example is incorrect (I'm learning something new every day). The VM checks during classloading if "Hello" has to be created or not (and will create a String instance if not existing yet).

So now it is my understanding, that the VM creates a String instance for each unique String literal (on byte code level!), regardless whether it is used or not.

(on byte code level because compilers may optimize concatenations of String literals to one literal, like: the expression "one"+"two" will be compiled to "onetwo")

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1503769

I'm not at all sure about the answers you've received so far. If you're just returning a string literal, e.g.

return "foo";

then those values are embedded into the class file. The JVM makes sure that only one instance of that string is ever created (from the literal) - but I don't think there's any guarantee that it won't create strings for all the constants in a class when the class itself is loaded.

Then again, because the string will only be created once (per string constant) it's unlikely to be an issue.

Now, if your code is actually more like this:

return "foo" + new Date();

then that is dynamically creating a string - but it will only be created if the return statement is actually hit.

Upvotes: 4

Gopi
Gopi

Reputation: 10293

  1. Right
  2. Right

Upvotes: 1

Kristof Mols
Kristof Mols

Reputation: 3557

Strings (and other objects) only get created when you call them.

So to answer your questions:

  1. Yes, only the String that gets returned will get created
  2. Yes, only when the exception is thrown, this String will get created

Upvotes: 0

Related Questions