0

I have two classes using the same String value, and both storing them as a final private field.

public class Foo{
    private final String str;
    private final Bar bar; //notice this

    public Foo(String in){
        this.str=in;
        this.bar=new Bar(in);       //option 1
        this.bar=new Bar(this.str); //option 2
    }
}

And here comes Bar:

public class Bar{
    private final String boo;

    public Bar(String in){
        this.boo=in;
    }
}
  • Does Java store the same object everywhere, or does it make a copy for each instance*?
  • Is your answer the same for both option 1 and 2?

*Intuition hints at the former but you can never be sure with Java.

Side question:
What I'm trying to do is this: Foo does some processing on str and uses Bar as a utility class. Conceptually Foo and str are closely linked together, but apart from the constructor, Foo doesn't touch str directly again, but only through Bar.

I thought about removing str from Foo's fields in fear of Java allocating the same string twice, which prompted this question. But from a software engineering / code correctness standpoint, should I remove it?

rath
  • 3,655
  • 1
  • 40
  • 53
  • 3
    _but you can never be sure with Java._ The Java Language Specification is extremely clear if you read it. – Sotirios Delimanolis Dec 12 '13 at 01:42
  • 3
    Also `final` has nothing to do with the actual object being referenced. It only limits the variable. – Sotirios Delimanolis Dec 12 '13 at 01:43
  • I thought `final` is treated the same as C's `const` at compile time. I thought wrong. And I could read [the entire spec](http://docs.oracle.com/javase/specs/)... or as a question here ;) – rath Dec 12 '13 at 01:47
  • 2
    I think you may be getting `final` confused with `static`. They are two different things, although they are both used with constants. One means "you can't change this"; the other means "there is only one copy". – Dawood ibn Kareem Dec 12 '13 at 01:49
  • @rath You say that with a wink as if nobody would read the spec. The spec for final has only 13 sentences and a short code example. – Radiodef Dec 12 '13 at 03:57
  • @radiodef The relevant spec section doesn't provide a direct answer (at least I don't see one). The full PDF is 670 pages long - I'm not reading that. I won't defend a silly question (as I now see it) but the wink was implying if everyone read the manual(s), this site would have a lot less traffic. But perhaps you're right, a wink is a bit confusing. – rath Dec 12 '13 at 12:36

1 Answers1

1

Since you don't instantiate another String instance, your options are all the same reference (in this example).

Considering your initial call(s), we could force them to have different reference values (I don't know why you would do this, and there are consequences - namely growing the intern cache);

this.str=in;
this.bar=new Bar(in);                     // option 1
this.bar=new Bar(this.str);               // option 2

This will change the references.

this.str = new String(in);                // <-- create a new String from in.
this.bar = new Bar(in);                   // <-- keeps the original reference to in.
StringBuilder sb = new StringBuilder(in); // <-- create a StringBuilder.
this.bar = new Bar(sb.toString());        // <-- create another String.
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249