Question

I have two classes, ThisTest and SimpleTime. The method buildString() returns a concatenated string with the "this" keyword. When I run it, "this" seems to refer to the method toString() and not the class SimpleTime. Why does the toString() method execute when I use the "this" keyword? Thanks.

import java.text.DecimalFormat;

import javax.swing.*;

public class ThisTest {

    public static void main(String args[]) {
        SimpleTime time = new SimpleTime( 12, 30, 19 );

        JOptionPane.showMessageDialog( null, time.buildString(), 
       "Demonstrating the \"this\" Reference", JOptionPane.INFORMATION_MESSAGE);

        System.exit(0);
    }
}

class SimpleTime {
    private int hour, minute, second;

    public SimpleTime( int hour, int minute, int second )
    {
        this.hour = hour;
        this.minute = minute;
        this.second = second;
    }

    public String buildString()
    {
        return "this.toString(): " + this.toString() + 
        "\ntoString(): " + toString() + 
        "\nthis (with implicit toString() call): " + this;
    }
    public String toString()
    {
        DecimalFormat twoDigits = new DecimalFormat("00");

        //"this" not required, because toString does not have
        //local variables with same names as instance variables
        return twoDigits.format( this.hour ) + ":" +
        twoDigits.format( this.minute ) + ":" +
        twoDigits.format( this.second );
    }

    public String anotherString()
    {
        return "Another String for you";
    }

}

Was it helpful?

Solution

Because that's what happens when you use the String concatenation operator (+).

It calls the toString() method of the object being added (which is guanateed to be there since it's defined in Object).

In your case, that's the current object (this) so you get this.toString() called. And because you've overriden toString() in your class, you get the result of that.

Edit to add: Note that there's no difference between + this and + this.toString(); you'll end up with the same result.

Specifically, this is covered by section 15.18.1 of the JLS

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.

And §5.1.11 states:

...

Now only reference values need to be considered:

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.

OTHER TIPS

The expression

String s = "literal" + object;

compiles to

String s = new StringBuilder().append( "literal" ).append( object ).toString();

If we have a look at the source code for StringBuilder#append(Object), we find:

public StringBuilder append(Object obj) {
    return append(String.valueOf(obj));
}

If we have a look at the source code for String.valueOf(Object), we find:

public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

So ultimately, the object's toString() method is called.

Blatantly plagiarising from DavidWallace's comment:

Section 15.18.1 states

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

and section 5.1.11 states

... 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 it seems the current JDK doesn't directly adhere to the JLS, but it gets there in the end.

This has nothing to do with this.
When used with strings, Java's + operator will implicitly call toString() on any non-string operand.

This is how expressions like "A" + 1 compile.

in this line:

 "\nthis (with implicit toString() call): " + this;

The operator '+' works with two strings, java implicitly call to the toString() method to obtain the string representation of the object referenced by this. write "this" or "this.toString()" is totally equivalent.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top