• 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
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Concatenating Strings

 
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Since I'd read somewhere that String's concat method and the concatenation operator + are equivalent, I expected to see them work the same way if I passed either the null literal or a null reference. But I'm seeing that if I start with the String "test" and concatenate either the null literal or a null reference with the +, I get "testnull" as a result, while using concat gives a runtime error whether it is the null literal or a null reference that is passed. Does anyone know what the operator and the method are doing differently which makes that happen? Thanks,
Kathy
 
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm not sure exactly what's happening differently - obviously they're not exactly the same, but I'd like to point you to the API Spec for String. In there, you'll find this under the concat method:


Throws:
NullPointerException - if str is null.

 
Kathy Hodgson
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you! After I followed the link you provided and read the documentation on concat, I thought I'd look in the Java Language Specification for the String concatenation operator and see what they were saying that was different from the concat description. I found this:
"If the reference is null, it is converted to the string "null" (four ASCII characters n, u, l, l). Otherwise, the conversion is performed as if by an invocation of the toString method of the referenced object with no arguments; but if the result of invoking the toString method is null, then the string "null" is used instead. "
But in the concat link, there wasn't any mention of such special treatment, so I guess that's why I'm seeing a difference.
 
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here is the source code for java.lang.String.concat(String)

When you invoke s.concat(t), the value of t is assigned to the parameter str. Then str.length() is invoked. If the value of str is null, a NullPointerException is thrown.
Why does concat invoke str.length()? concat creates a new character array whose length is the length of the old string + the length of the string to concatenate.
Notice (and remember for future questions) that if the length of the string to concatenate is 0 (an empty string ��), concat does not create a new String object. Instead it returns �this�, the original String object.
[ July 25, 2003: Message edited by: Marlene Miller ]
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here are byte codes for the + operation on string operands with my comments.

Method void m()
// s1 = "test"
0 ldc #2 <String "test">
2 astore_1
// s2 = null
3 aconst_null
4 astore_2
// StringBuffer sb = new StringBuffer()
5 new #3 <Class java.lang.StringBuffer>
8 dup
9 invokespecial #4 <Method java.lang.StringBuffer()>
// sb = sb.append(s1)
12 aload_1
13 invokevirtual #5 <Method java.lang.StringBuffer append(java.lang.String)>
// sb = sb.append(null)
16 aconst_null
17 invokevirtual #6 <Method java.lang.StringBuffer append(java.lang.Object)>
// s3 = sb.toString()
20 invokevirtual #7 <Method java.lang.String toString()>
23 astore_3
// StringBuffer sb = new StringBuffer()
24 new #3 <Class java.lang.StringBuffer>
27 dup
28 invokespecial #4 <Method java.lang.StringBuffer()>
// sb = sb.append(s1)
31 aload_1
32 invokevirtual #5 <Method java.lang.StringBuffer append(java.lang.String)>
// sb = sb.append(s2)
35 aload_2
36 invokevirtual #5 <Method java.lang.StringBuffer append(java.lang.String)>
// s4 = sb.toString()
39 invokevirtual #7 <Method java.lang.String toString()>
42 astore 4
44 return
[ July 25, 2003: Message edited by: Marlene Miller ]
 
Kathy Hodgson
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you, Marlene. I see where concat runs into trouble with null now. I'm not sure I understand everything you've got in that second note ( where does all that code come from? Is that what Java turns into when you compile it? ) but it looks like it takes a totally different approach which avoids the null problem.
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Almost done...
When s1 + null is evaluated, this StringBuffer method is called.

When s1 + s2 is evaluated, this StringBuffer method is called

Both overloaded StringBuffer append methods call this String method

So this is where the operand with null value is converted to �null�, in String.valueOf(Object).
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What I have learned is
(1) String objects are internally char arrays. The String concat method creates a new char array, fills it and creates a String object from the char array.
(2) the + operator creates a StringBuffer object, appends Objects and Strings and creates a String object from the StringBuffer object.
(3) concat(null) blows up because of str.length()
(4) s + null does not blow up because StringBuffer.append calls String.valueOf which replaces null with "null"
Phwew!
(So, the next time someone tells us + and concat are the same, we will raise our eyebrows and just say Is that so?)
[ July 25, 2003: Message edited by: Marlene Miller ]
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

( where does all that code come from? Is that what Java turns into when you compile it? )


Yes. It is the file of byte codes after compiling Java source code.
javac Test.java
javap -c Test
Even if it looks strange, you don't have to understand everything. Just look at the loads and stores and the familiar names of the methods.
 
Kathy Hodgson
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you, that is really clear now - and I sure will raise my eyebrows next time some one says they are the same!
 
Ranch Hand
Posts: 247
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


Notice (and remember for future questions) that if the length of the string to concatenate is 0 (an empty string ��), concat does not create a new String object. Instead it returns �this�, the original String object.


Exactly the same happens for the methods trim, toUpperCase, toLowercase, or replace. If one of these methods (+concat) is invoked on a String object that requires no changes, then a reference to the existing String instance is returned.
So ,by example,
 
cyril vidal
Ranch Hand
Posts: 247
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
On the same topic, something that's worth knowing:

will output null (refer to the Marlene's explanations (null value is converted to �null�, in String.valueOf(Object)).
but

will generate a compiler error:


because reference to append is ambiguous in this case: both method append(String s) and append(char[] c) of StringBuffer match s2.append(null).

 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

will generate a compiler error:


When I looked at the byte codes and saw that the + operator was using the StringBuffer method, I wondered how sb.append(null) worked. Then I noticed the compiler chooses append(Object) (see lines 16 and 17). Interesting.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic