• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Liutauras Vilda
  • Paul Clapham
  • paul wheaton
Sheriffs:
  • Tim Cooke
  • Devaka Cooray
  • Rob Spoor
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Tim Moores
  • Carey Brown
  • Mikalai Zaikin
Bartenders:

String concatenation

 
Ranch Hand
Posts: 133
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Can somebody explain this for me?
class Try {
public static void main(String[] args) {
String sb1 = "good";
String sb2 = "";
System.out.println(sb1==sb1+sb2);
}}
Output is false. It seems sb1+sb2 creates a new String, because String is immutable;
However:
class Try {
public static void main(String[] args) {
String sb1 = "good";
String sb2 = "";
System.out.println(sb1=="good"+"");
}
}
returns true. Why the concatenation of two string literals and two String objects have different effects.
To make things even murky, consider the following:
class Try {
public static void main(String[] args) {
String sb1 = "good";
String sb2 = "";
System.out.println(sb1==sb1.concat(sb2));
}
}
returns true. Therefore + and concat() seem to have different effects as well.


 
Ranch Hand
Posts: 78
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That is the trick of SUN java, and i think Sun should chang the situation of String in the future. The following statement explain the magic:
>
About STring.concat(<string>) method :
If the length of the argument string is 0, then this String object is returned. Otherwise, a new String object is created, representing a character sequence that is the concatenation of the character sequence represented by this String object and the character sequence represented by the argument string.</b/i>

if you change the "" to "1a" or other any signal, the result of boolean is false. it is same for String.concat(). u can try it.
ur question is interesting.
regds
George
 
Tom Tang
Ranch Hand
Posts: 133
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, George:
I think the API you cited only explain the following
code:
String s1="good";
String s2="";

System.out.println(s1==s1.concat(s2));
//return true because referring to the same object
System.out.println(s1==s2.concat(s1));
//return false because referring to the different object
System.out.println(s1.equals(s2.concat(s1)));
//return true because comparing two indentical object.
Can someone shed more light on my original question?
 
George Toronto
Ranch Hand
Posts: 78
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, Tom
i suppose the performance of s1=="good"+"" is same as s1=s1.concat(""). i am not sure that point since i didnot find the rule from meterial java in my hands. it is just like i can not find where the original quote is from:

sometimes, you can check the trival concepts by practice it, right?
regds
georeg

 
Tom Tang
Ranch Hand
Posts: 133
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi George:
I think you are right. + and concat() should have the same effect in this example. After reading the back postings about String at Ranch, I believe "good"+"" is the same as "good" in the String pool, but s1+s2 just creates an average String object which has a different memory position, therefore the == operator produces different results.
 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Stranger and stranger!
sorry I can't answer your question Tom but it did prompt some investigation and experimentation on my part. Check it out.
This is from the source StringBuffer.java:


* String buffers are used by the compiler to implement the binary
* string concatenation operator <code>+</code>. For example, the code:
*
<blockquote><pre>
* x = "a" + 4 + "c"
* </pre></blockquote>

* is compiled to the equivalent of:
*
<blockquote><pre>
* x = new StringBuffer().append("a").append(4).append("c")
* .toString()
* </pre></blockquote>
and here is the implementation of the StringBuffer.append(String) method:
public synchronized StringBuffer append(String str) {
if (str == null) {
str = String.valueOf(str);
}
int len = str.length();
int newcount = count + len;
if (newcount > value.length)
expandCapacity(newcount);
str.getChars(0, len, value, count);
count = newcount;
return this;
}
I read this. So far so good and then I tried this:
class Try2 {
public static void main(String[] args) {
String sb1 = "good";
String sb2 = "";
System.out.println(sb1==(new StringBuffer().append("good").append("").toString()));
System.out.println(sb1=="good"+"");
}}
The first println contains what the documentation "in the source from Sun" says happens when you write what is contained in the second println. The two, according to Suns own docs should be equivalent but they aren't.
The output is, you guessed it: "false" and "true".
My best guess? The compiler is optimizing out the +"" in the second println since it cannot have any affect on the content. And since "good" is a String literal it is added to the classes String pool at compile time so that any String referenced by the class or an instance of the class with the contents "good" will get the same reference.
My second guess? The String is added to the classes string pool as above and there is some mechanism in the JVM itself that short circuits this kind of thing so that the +"" is never actually executed.
Unfortunately we don't have access to the code that implements the operators or the code for the compiler (or the time, patience and knowledge to go through them). I wonder if this code would run differently on a different compiler and/or differenct JVM? Anybody?
One more thing that may be of interest: If you insert the following code between the two println statements in the above code the output is "false" "true" "true":
System.out.println(sb1=="good".concat(""));
The source shows why this is the case:
From String.java
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
//code snipped for brevity
}
Kinda interesting Huh?
 
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Tom,
I think here is the answer to your question. I have taken your example and added some more code to it to explain.
public class strcon
{
public static void main(String args[])
{
String s1 = "qrst";
String s2 = "wxyz";
int val1 = 6;
int val2 = 5;
byte b1 = 2;
byte b2 = 3;
StringBuffer sb1 = new StringBuffer("abcd");
StringBuffer sb2 = new StringBuffer("efgh");
System.out.println( s1+ val1);
System.out.println(val2 + val1);
System.out.println( val2 + " " + val1);
System.out.println( b1 + b2);
System.out.println( b2 + " " + b1);
//System.out.println(sb1 + val); //Gives compiler error
//System.out.println(sb1 + sb2); //Gives compiler error
System.out.println(s1 + s2);
System.out.println(sb1 + s2);
}
}

//Can anybody explain why (sb1+s2) doesn't give an error?

Explanation: + and += operators are designed for concatenation of strings and numbers. If you want to concatenate, at least one of the concatenating elements MUST be a STRING. If you try to concatenate two numbers, it simply does the ADDITION. Try the above class. StringBuffer & String are totally different classes, so StringBuffer does not work as String. That's why
System.out.println(sb1 + val);
System.out.println(sb1 + sb2);
gives compiler errors. Hope it might help you out.
Mondal
 
Ranch Hand
Posts: 3141
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi all,
When you create a String using new or when the String is the result of a runtime operation Java creates a new object.
If the String is a literal; the result is placed in a 'string pool'. If the the String already exists in the pool, a reference to the pre-existing string is returned.
In the first example:

sb1 and sb2 are evaluated at Runtime therefore a new String object is returned. As the == operator compares Objects, the result is false ... the new object is not the same as the 'sb1' object.
In the second example:

"good"+"" is a String literal evaluates to the String literal "good". String literals are known at compile time and the literal "good" already exists in the string pool so a new object is not created; instead a reference to "good" in the string pool is returned. As 'sb1' points to this same string in the pool; the result of "==" is true.
In the third example:

The 'concat()' operator does not return a 'new' object as no change occurs ie the resulting string is still equal to "good" therefore the original object reference is returned.
Refer to JLS §3.10.5 on String Literals and the API for the concat() method.
Hope that helps.
------------------
Jane
The cure for boredom is curiosity.
There is no cure for curiosity.
-- Dorothy Parker
 
George Toronto
Ranch Hand
Posts: 78
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, jane
Thank you very much. Your expaination is clear and convinced. So I think I should read JLS carefully. But, do you think it is a must for clearing the exam?
Thanks again
George
 
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Tom Tang:
Can somebody explain this for me?
class Try {
public static void main(String[] args) {
String sb1 = "good";
String sb2 = "";
System.out.println(sb1==sb1+sb2);
}}
Output is false. It seems sb1+sb2 creates a new String, because String is immutable;


Hi,Tom
i check your code above on JBuilder,and the output is true. i think if you don't create a String instance use the keyword new,the condition expression (sb1==sb1+sb2) is as same as (sb1==sb1+""),bcos they reference to the same string "good" in the String pool,which has the unique memory address.
regds,
meyer

 
meyer
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Jane Griscti:
Hi all,
When you create a String using [b]new
or when the String is the result of a runtime operation Java creates a new object.
[/B]


Hi,Jane
when the String is the result of a runtime operation Java creates a new object.
Would you like to tell me the source of this rule?
i run the first example on JBuilder3.5 (JDK1.2) and the output is true,so i am confused.pls help me
thanks a lot
regards,
meyer
 
George Toronto
Ranch Hand
Posts: 78
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There is a good review about String.
 
Jane Griscti
Ranch Hand
Posts: 3141
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
meyer, George ....
Sorry for the late response, I lost track of the post.
George, I found reading the JLS and working through the code examples very helpful.
Meyer,
JLS § 4.3.1 states:


A new class instance is implicitly created when the string concatenation operator + (�15.18.1) is used in an expression,
resulting in a new object of type String (�4.3.3)


I believe the Java Programming Language stated the same for any String created at runtime (I'll have to check, the book is at home and I'm at work .
I just recompiled the example using JDK 1.3 and it does come up false. I'm not sure why JBuilder would report differently. Do you have the JDK installed? Try compiling the command line.
Hope that helps.
------------------
Jane
The cure for boredom is curiosity.
There is no cure for curiosity.
-- Dorothy Parker
 
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Try this following code:

public Class StringTest {
public static void main(String[] args) {
String p1, p2;
p1 = "Paul";
p2 = new String(p1);
System.out.println(p1==p2);
System.out.println(p1=="Paul");
System.out.println(p2=="Paul");
}
}

The output is

false, true, false

The fact is that String p2 = new String(p1) will always create a copy of "Paul". I am 100% sure.
I had mail on such a question. See it, it's from Barry Boone:

There are a number of labels in the source code below. These are
labeled a
through j. Which label identifies the earliest point where, after that
line has executed, the object
referred to by the variable first may be garbage collected?
class Riddle {
���� public static void main(String[] args) {
��������� String first, second;
��������� String riddle;
��������� if (args.length < 2)
��������� return; a: first = new String(args[0]);
��������� b: second = new String(args[1]);
��������� c: riddle = "When is a " + first;
��������� d: first = null;
��������� e: riddle += " like a " + second + "?";
��������� f: second = null;
��������� g: System.out.println(riddle);
��������� h: args[0] = null;
��������� i: args[1] = null;
��������� j:�
�������������� }
��������� }

Select the one right answer.
� a.d:
� b.e:
� c.h:
� d.i:
� e.j:
Answer is A
 
If I had asked people what they wanted, they would have said faster horses - Ford. Tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic