5

In Java, apparently, String s = "foo" is preferred over String s = new String("foo").

Why? Isn't a new string object created in both cases? Why would the first case preclude calling a constructor?

dangerChihuahua007
  • 20,299
  • 35
  • 117
  • 206
  • possible duplicate of [What is the difference between "text" and new String("text") in Java?](http://stackoverflow.com/questions/3052442/what-is-the-difference-between-text-and-new-stringtext-in-java). (Once you understand the difference between the two forms, it is obvious why the first is preferred ... in almost all cases.) – Stephen C Jun 23 '12 at 23:42

4 Answers4

9

Why?

Because the second approach results in two string objects (the original due to the string literal, plus an explicit copy).

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • The second approach results in two string objects - only when "foo" is not already in the String pool. – Kazekage Gaara Jun 24 '12 at 02:38
  • @KazekageGaara, to reference `"foo"` it must be in "the pool" already. It's declared in the class' constant pool and it's put there while the class (or the concrete method) is processed by the JVM – bestsss Jun 26 '12 at 08:55
4

The first case is a string literal, simply a shorthand the language offers you to create a string. The String class constructor still gets called, just not explicitly, which means less typing and less code clutter.

The second case takes the String object already created by the literal and passes it to a constructor, which copies the content to create a new, separate String object. The literal will still be around because literals are interned.

There is rarely a point to using the String constructor (pretty much only when you've created a substring of a very large string and want to release the memory used by the rest of the string, because substrings by default use the same underlying char array as the original string, just with a different offset and length.

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
  • small point: *The literal will still be around because literals are interned.*, if the literal has no incoming references (like being in a class' constant pool) it's free to be GC'd, effectively freeing the perm-gen (provided the JVM uses perm-gen, some don't) – bestsss Jun 26 '12 at 08:51
  • @bestsss: But aren't literals always part of the constant pool? – Michael Borgwardt Jun 26 '12 at 09:26
  • 1
    The constant pool is part of its class. Declared String out of the constant pool go to the perm-gen (under Suns JVM, some JVMs do not use perm-gen). But after the class+classloader are GC'd, the JVM is free to "free" the interned instance as well. Otherwise all classnames, literals, etc will leak after 'undeploy'/'redeploy' – bestsss Jun 26 '12 at 11:44
  • @bestsss: OK, we're on the same page now. I've worked too much on desktop applications to consider class unloading a regularly ocurring case. – Michael Borgwardt Jun 26 '12 at 11:50
  • I guess so :) I do a lot of middleware and class unloading is everyday's business, so basically anything that doesn't come from either the bootstrap or application classloader is a free game. – bestsss Jun 26 '12 at 11:54
1

I don't think it's preferable. I assume the only "benefit" you get is that if you wrongfully use the "==" operator rather than the equals method, have two different instances of a string will fail faster which will prompt you to fix your code. (the == operator may "succeed" and fail unpredictably)

Unless of course your code requires you to construct two different instances for whatever reason

Savvas Dalkitsis
  • 11,476
  • 16
  • 65
  • 104
  • Requiring two different instances of a `String` (with identical content) sounds about as good as requiring two different "instances" of an `int`... perhaps there is some poor abused identity map somewhere... but I hope not :-/ –  Jun 23 '12 at 23:32
  • Yes, given the fact that String is immutable, I can't think of any reason why anyone would require such a thing. That is why I said "for whatever reason" – Savvas Dalkitsis Jun 23 '12 at 23:34
1

Why? Isn't a new string object created in both cases?

No, the initial form being a string literal will be interned such that only one instance is created:

String s = "foo";
String s2 = "foo";

s == s2 => true

John Earles
  • 7,194
  • 2
  • 37
  • 35