简体   繁体   中英

How can java class instance be added with string?

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 the toString 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM