aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Concatenating Strings Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Concatenating Strings" Watch "Concatenating Strings" New topic
Author

Concatenating Strings

Kathy Hodgson
Greenhorn

Joined: Jun 16, 2003
Posts: 28
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
Corey McGlone
Ranch Hand

Joined: Dec 20, 2001
Posts: 3271
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.


SCJP Tipline, etc.
Kathy Hodgson
Greenhorn

Joined: Jun 16, 2003
Posts: 28
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.
Marlene Miller
Ranch Hand

Joined: Mar 05, 2003
Posts: 1391
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

Joined: Mar 05, 2003
Posts: 1391
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

Joined: Jun 16, 2003
Posts: 28
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

Joined: Mar 05, 2003
Posts: 1391
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

Joined: Mar 05, 2003
Posts: 1391
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

Joined: Mar 05, 2003
Posts: 1391
( 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

Joined: Jun 16, 2003
Posts: 28
Thank you, that is really clear now - and I sure will raise my eyebrows next time some one says they are the same!
cyril vidal
Ranch Hand

Joined: Jul 02, 2003
Posts: 247

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,


SCJP 1.4, SCWCD, SCBCD, IBM XML, IBM Websphere 285, IBM Websphere 287
cyril vidal
Ranch Hand

Joined: Jul 02, 2003
Posts: 247
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

Joined: Mar 05, 2003
Posts: 1391
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.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Concatenating Strings