public class ProductTest{
public static void main(String[] args){
Product pr=new Product();
System.out.println(pr); /// Product@hashcode
}
}
class Product{
}
I can understand the above output of Product@hashcode since println
method internally uses valueOf
method and converts it into the string.
But I cannot explain the behavior of output below,
public class ProductTest{
public static void main(String[] args){
Product pr=new Product();
String str=pr + "something";
System.out.println(str); // Product@hashcodesomething
}
}
class Product{
}
How can class instance and string literal be added together?
What am I missing?
It is simple.
String str=pr + "something";
It is equal to
pr.toString() + "something";
and pr.toString by default return the Product@hashcode
And that is why we get
System.out.println(str);
You can change your toString method of your object and you will see the changes. --- Going a Little Depeer All Classes extends by default the toString Method of the Object that is equal to
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
So whenever we try to make a contact of a String It is happening like mentioned before
pr.toString() + "something";
If you change your class to override the default method of toString :
class Product{
@Override
public String toString() {
return "This is my String plus";
}
}
The output will be
This is my String plussomething
I hope this clarifies
This is specified in the Java Language Specification §15.18.1 :
If only one operand expression is of type String, then string conversion ( §5.1.11 ) is performed on the other operand to produce a string at run time.
A string conversion is further specified like this:
Any type may be converted to type String by string conversion.
[...]
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 thetoString
method is null, then the string "null" is used instead.
So something like pr + "something"
is equivalent to String.valueOf(pr) + "something"
.
Note that I used valueOf
instead of toString
, because pr.toString()
would throw an exception in case pr
is null. String.valueOf()
would not.
If you look at the byte
code generated by your it will be clear:
8: new #19 // class java/lang/StringBuilder
11: dup
12: invokespecial #21 // Method java/lang/StringBuilder."<init>":()V
15: aload_1
16: invokevirtual #22 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
19: ldc #26 // String something
21: invokevirtual #28 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
24: invokevirtual #31 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
27: astore_2
So, from the above byte code, it is clear that Java compiler has compiled to your String str=pr + "something";
line of code same to the below code.
String str = new StringBuilder()
.append(pr)
.append( "something")
.toString();
Now if you look at the StringBuilder#append(Object obj)
ir uses String.valueOf(obj)
which further calls obj.toString()
:
@Override
public StringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.