-1

I have heard that two objects are created when you execute String s = new String("lol");. One object is created for the string constant pool and one for s on the heap.

So, are 2 objects created when we execute the following? String s = "lol"; Is the object creation the same?

Edit:

how many objects are created by : String s1 = new String("lol1");

and how many by : String s2 = "lol2";

donsalari
  • 61
  • 1
  • 2
  • 10
  • 2
    Actually, "lol" in the constant pool is created when the first String literal for that value is loaded in any class -- could be a class loaded 10 minutes ago. And simply assigning an object reference value to an object reference variable does not create any objects. – Hot Licks Feb 07 '14 at 22:08
  • Related (but to a different question): http://stackoverflow.com/questions/1855170/when-should-we-use-intern-method-of-string-on-string-constants also http://stackoverflow.com/questions/10672402/javaliteral-strings?rq=1 – user2864740 Feb 07 '14 at 22:08
  • No. One is a literal value, and one is an object. – Alex Johnson Feb 07 '14 at 22:08
  • 4
    @AlexJohnson - A String literal is an object. – Hot Licks Feb 07 '14 at 22:08
  • @HotLicks Indeed, which is why, until Java gets a null coalescing operator like C#'s `??`, `"expectedValue".equals(someStringVariableThatMayBeNull)` is such a useful construct in the real world. :) – user Feb 07 '14 at 22:09
  • @HotLicks Not just a grammar production? ;-) – user2864740 Feb 07 '14 at 22:09
  • @HotLicks Touche, nice catch. I was meaning the object as a string object, and the other as just a string. Poor choice of words using literal. – Alex Johnson Feb 07 '14 at 22:21
  • What is "just a string" (but presumably not an "object") in Java? – Hot Licks Feb 07 '14 at 22:23

2 Answers2

6

No, with String s = "lol";, only one object is created. With every string literal, a String object is created and placed in the string pool. Here, s just refers to that pooled string. When you say s = new String("lol"), the string literal is created and pooled, and another string is allocated and assigned to s, which is a different, yet equal, string.

UPDATE

I had forgotten about the char[] that is used internally by a String object.

String s1 = "lol";

2 objects are created, the char[] that holds {'l', 'o', 'l'} and the String object that references it internally. It's interned in the string pool.

String s2 = new String("lol");

3 objects are created. First, the string literal: 2 objects are created, the char[] that holds {'l', 'o', 'l'} and the String object that references it. It's interned in the string pool as before. Then, the new String object that gets assigned to s2: A new String is created, but it references the same char array as the original string. Two String objects, and one char[] object. (The String(String) constructor may make a copy of the char[] in the circumstance that the original string's array's length is somehow greater than its count, but that doesn't appear to be the case here.)

rgettman
  • 176,041
  • 30
  • 275
  • 357
  • 2
    Actually, zero objects created, if the earlier statement referencing "lol" is still in the class. There is (at most) only one representation of the literal value "lol" anywhere in the entire JVM. – Hot Licks Feb 07 '14 at 22:10
  • @HotLicks I had interpreted the question to mean that the two statements were different examples, not two lines in the same program. – rgettman Feb 07 '14 at 22:14
  • You would not get just one, a `String` wraps a `char[]` so there is likely to be two, or none. – Peter Lawrey Feb 07 '14 at 22:18
  • @PeterLawrey - A String doesn't necessarily wrap a `char[]`. – Hot Licks Feb 07 '14 at 22:19
  • Ok one follow up question : why are Two String objects created in case of `String s2 = new String("lol");` ? – donsalari Feb 07 '14 at 23:18
  • One for the string literal, and one for the new `String` object created by `new`. – rgettman Feb 07 '14 at 23:22
  • @HotLicks How would describe the relationship between the `String` and the `char[]` in it? See the `String(int offset, int count, char value[])` constructor http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/String.java#String.%3Cinit%3E%28int%2Cint%2Cchar%5B%5D%29 – Peter Lawrey Feb 08 '14 at 08:20
  • @PeterLawrey - Who says there has to be a `char[]` in it? Maybe in that particular implementation, but there's nothing in the spec that requires it. The iSeries "classic" JVM didn't have a `char[]` in most Strings. Using a `char[]` inside String is a major performance hit. – Hot Licks Feb 08 '14 at 13:05
  • @HotLicks Unless you are talking about how the JVM usually works there is no actual requirement to create an object and it could allocate on the stack or optimise it away completely. OpenJDK, which is the reference implementation for the JVM, uses a `char[]` and you can reasonably expect most JVMs will also. – Peter Lawrey Feb 08 '14 at 13:24
  • You can't legally optimize away the creation of an object. And an object created on the stack is still an object. (And the meaning of "reference implementation" is "slow".) – Hot Licks Feb 08 '14 at 13:27
3

"lol" is a String literal - when you reference it in your code, you force Java to create this object. The second object you're seeing is when you explicitly call String's constructor with the new operator. Assigning these values to other variables does not create additional objects.

Mureinik
  • 297,002
  • 52
  • 306
  • 350
  • 1
    It should be noted that only one instance of "lol" is created for the life of the JVM, regardless of how many classes use the literal how many times. `new String`, however, creates a new object every time it executes. – Hot Licks Feb 08 '14 at 13:07