1

Ok, I know that String objects are immutable, so if I need to "copy" the string content from a given string A to another one B I can assign the reference to A like (method 1):

String B = A;

instead of (method 2)

String B = new String(A);

because since there's no way to modify A I'm sure that by referring to B I obtain the same character sequence. Right?

But what happens in this situation described below?
I have a class C that has a String field "subject" and a constructor that take as argument a String "arg" and it must initialize subject to a character sequence equal to the one of "arg".

I have the following code:

public C getSomeC(...){

   // some code to set the String A that is defined inside this function

   return new C(A);

}

This way I simply call getSomeC(.) from some other point in my program so as to get my C instance.
But what changes whether I use method 1 or 2 in the constructor of C to define C.subject?
If I use the method 1 I pass to C constructor by value the reference of A and I assign to subject the reference to A right? But A has a visibility limited to method getSomeC(..) While I want my C instance to be used outside that method. What happens inside java in this case? Does the reference A be destroyed at the end of getSomeC(.) while the object remains alive because referred by instanceofC.subject?

What if I use method 2 instead?

1
  • 2
    Joffrey's answer is correct. If you want to learn more about this you should look up how Java uses the String pool. Commented Apr 17, 2014 at 12:53

4 Answers 4

1

In short, both methods are fine, your String will be kept, but you should prefer method 1 as it does not create unnecessary objects, as @Paul pointed out.

But A has a visibility limited to method getSomeC(..)

The variable A has this visibility, not the object pointed by A.

What happens inside java in this case? Does the reference A be destroyed at the end of getSomeC(.) while the object remains alive because referred by instanceofC.subject?

The String object will exist outside of the method's scope, as long as some reference to it is kept somewhere. And this is the case. Indeed, a reference is kept in your C object, that's why you're fine.

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

4 Comments

So it is totally useless the method 2 since does the same thing by creating a new object?
@mb_ Exactly. No need for new.
Method two is not so good as it unnecessarily creates a new String.
@Paul right, I updated my answer to make a note about it. Thanks
1

You are confusing variable scope with object lifetime. Your variable A is only visible inside getSomeC(). But the strin object that variable points to is not applicable from garbage collection until it is not referenced anymore. So, if you pass it to teh constructor and assign it to a field, that field still point to the string object and it persists.

Besides that I'd prefer the first method. String B = new String(A); explicitly creates a new string object that represents the same value. With String B = A; you'll only have one object and save memory. It might not seem much but in big systems or if you do this in many iterations, this can make a difference.

Comments

0

I'm not sure I understand your last paragraph. However, there is basically no reason to ever use: String newString = new String(oldString);. You can always just use: String newString = olString;. (The inclusion of a constructor taking a String and returning a new String that is a copy of the original has been considered a mistake by many since, being immutable, is it better to just reuse the original String.)

The only exception would be if forced to deal with dodgy code relying on the identity (rather than the value) of a String.

Comments

-1

You are right - strings are immutable in Java. Which means, that everytime you do something with string a new string with new contents is created.

The only difference is that when you explicitly call new operator it creates a brand new String, which is not taken from so-called "string pool".

E.g.:

"A" == "A"

can be true (not guaranteed, though), but

"A" == new String("A")

is always false.

8 Comments

Your first statement is incorrect. There is a relatively high probability that the same string object is used for two equal character sequences but it is not guaranteed. "A" == "A" can be false.
@André Stannek Provide a proof then!
Ok, agree. In some cases, it can be false.
I'm also interested in, in which case the first statement will not be true? In my opinion, the JVM creates an internalized string at the first "A" and on the second it reuses exactly the same string. That's why the reference of these objects should always be equal, shouldn't it?
Let's put it this way: you are gonna try really hard to find when it equals to false, but as it's not guaranteed by the specification therefore you can not rely on it in a production environment.
|

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.