-16
String s1 = new String("abc");
String s2 = "abc";

In s1 there will be two objects created, one in the string pool and one in non-pool memory.

In s2 there will be only one object created, in the string pool.

If we do:

s1.concat("def");
s2.concat("def");

There are now 3 objects in string pool ("abc", "def", and "abcdef"), two are abandoned ("def" and "abcdef") leaving "abc" in memory.

Both references are referencing a string pool object.

What's the significance of memory object?

dimo414
  • 47,227
  • 18
  • 148
  • 244
  • 2
    What do you mean "what's the significance of memory object?"? – Maroun May 12 '15 at 06:39
  • 3
    Why do you think that *"abcdef"* will be in the string pool? – Tom May 12 '15 at 06:39
  • Nope. `"abcdef"` will not go into *String constants pool*. – TheLostMind May 12 '15 at 06:40
  • 1
    Also, "abcdef" will be candidate for garbage-collection, because you're not assigning the result of concat() to any variable. concat() doesn't modify the string. It creates a new one. – JB Nizet May 12 '15 at 06:46
  • i know about that thats why i asked. – Purvender Hooda May 12 '15 at 07:03
  • @MarounMaroun its referencing only to the string pool then why make two objects one in heap and one in string pool while initiating first. – Purvender Hooda May 12 '15 at 07:06
  • @Tom "abcdef" will go in string pool. Because thats how out BM handles String – Purvender Hooda May 12 '15 at 07:07
  • @TheLostMind "abcdef" will go in string pool. Please check some basic java resources. – Purvender Hooda May 12 '15 at 07:07
  • @JBNizet very true but its referencing only to the string pool then why make two objects one in heap and one in string pool while initiating first – Purvender Hooda May 12 '15 at 07:08
  • 4
    @PurvenderHooda you seem be convinced that you know better than everyone out here. Then why are you asking? No, the result of s1.concat("def") won't go into the string pool. And I can't understand what you're asking me. – JB Nizet May 12 '15 at 07:11
  • 1
    @PurvenderHooda - I am not talking about the *string literal* `"abcdef"`. I am talking about the string `abcdef` generated by `s1.concat("def")`. I assure you, it *does not* go into *String constats pool*. – TheLostMind May 12 '15 at 07:52
  • @JBNizet Thats basics.Thanks anyways. I will find out that one. for a little proof: – Purvender Hooda May 12 '15 at 08:25
  • @TheLostMind String s1 = new String("abc"); now do s1.concat("def"); , there is a change in object. so SOP(s1) should be "abcdef" not "abc". Please check first and then do reply. – Purvender Hooda May 12 '15 at 08:25
  • @JBNizet String s1 = new String("abc"); now do s1.concat("def"); , there is a change in object. so SOP(s1) should be "abcdef" not "abc". Please check first and then do reply. – Purvender Hooda May 12 '15 at 08:28
  • 1
    Why don't you test by yourself first? BTW, you were already told twice that concat() doesn't change the string. It creates and returns a new one. SOP(s1) will not print "abcdef". It will print "abc. – JB Nizet May 12 '15 at 08:31
  • @JBNizet I am asking you a very simple question: ie, at object creation if we wrote Strinf s1= new String("abc"); then there be object formation. Total 2 objects. s1 is referencing to object of pool or object of memory(JVM not pool). whats the significance of other object. – Purvender Hooda May 12 '15 at 08:31
  • *"now do s1.concat("def"); , there is a change in object."* So you're telling us that `#concat` changes the _immutable_ String `s1`? Even the [JavaDoc](http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#concat%28java.lang.String%29) proves you wrong. – Tom May 12 '15 at 09:02

2 Answers2

4

In s2 there will be only one object created, in the string pool.

Actually no, this line will create no new objects. s2 will be a reference to the same constant used to construct s1.

There are now 3 objects in string pool ("abc", "def", and "abcdef"), two are abandoned ("def" and "abcdef") leaving "abc" in memory.

No, only "abc" and "def" are in the constant pool, and since they are constants they will remain in memory for the duration of the program. "abcdef" will be garbage collected promptly after it is constructed since it is never stored anywhere.

Had you used the + operator instead of String.concat() the compiler would in fact merge two constant strings into one, and only store the resulting string in the pool.

Both references are referencing a string pool object.

No, only s2 references a string in the constants pool, and neither result of .concat() will be in the constants pool.

What's the significance of memory object?

Are you asking what the point of the string constants pool is? It's essentially just an optimization to allow constants (i.e. "-ed strings in your code) to share the same reference to avoid constructing numerous identical instances. Because they're constants, this can be done at compile-time, saving both space and time at runtime. This does not apply to any strings constructed at runtime unless you explicitly call .intern(), however you should generally avoid doing so.

You may also be interested in Where does Java's String constant pool live, the heap or the stack?


Edit: since you're insisting that "abcdef" in your example will be part of the constants pool, here's simple proof that is not the case:

$ javac -version
javac 1.7.0_02

$ cat Test.java
public class Test {
  public static void main(String[] args) {
    String s1 = "123" + "456";
    String s2 = "abc".concat("def");
  }
}

$ javac Test.java

$ javap -c -classpath . Test
Compiled from "Test.java"
public class Test {
  public Test();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: ldc           #2                  // String 123456
       2: astore_1
       3: ldc           #3                  // String abc
       5: ldc           #4                  // String def
       7: invokevirtual #5                  // Method java/lang/String.concat:(Ljava/lang/String;)Ljava/lang/String;
      10: astore_2
      11: return
}

As you can clearly see, the strings 123456, abc, and def are constants (see ldc), and String.concat() is called at runtime.

Community
  • 1
  • 1
dimo414
  • 47,227
  • 18
  • 148
  • 244
  • 1
    Note that in the given context `abc`, `def` , `123456` are *class constants* and *not constants of String constant pool*. i.e, A class constant != String constant pool (not always) – TheLostMind May 12 '15 at 07:56
2

s1.concat("def"); and s2.concat("def"); are happening at runtime, they won't be part of the constant pool, they goes to the heap.

Note the signature of concat:

public String concat(String str)

it returns a new string, and you're not assigning that string to any variable.

What's the significance of memory object?

It's unclear what you're asking, but note that since the string created by concat is not assigned (references to it are discarded), it'll be eligible for garbage collection.

Maroun
  • 94,125
  • 30
  • 188
  • 241
  • They will be a part of string constant pool. we are not assigning any value, question is about total number of objects and where they reside in which memory. – Purvender Hooda May 12 '15 at 07:04