当使用“this”关键字时,Java隐式调用toString()

时间:2014-02-02 00:28:43

标签: java methods this tostring implicit

我有两个类,ThisTest和SimpleTime。方法buildString()返回带有“this”关键字的连接字符串。当我运行它时,“this”似乎引用了方法toString()而不是类SimpleTime。为什么在使用“this”关键字时toString()方法会执行?感谢。

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";
    }

}

4 个答案:

答案 0 :(得分:1)

因为这是使用字符串连接运算符(+)时发生的情况。

它调用正在添加的对象的toString()方法(由于它是在Object中定义的,因此它被指定为存在)。

在您的情况下,这是当前对象(this),因此您可以调用this.toString()。而且因为你在课堂上覆盖了toString(),你就得到了结果。

编辑添加:请注意+ this+ this.toString()之间没有区别;你最终会得到相同的结果。

具体而言,section 15.18.1 of the JLS

涵盖了这一点
  

如果只有一个操作数表达式是String类型,则在另一个操作数上执行字符串转换(第5.1.11节)以在运行时生成字符串。

并且§5.1.11声明:

  

...

     

现在只需要考虑参考值:

     

如果引用为null,则将其转换为字符串“null”(四个   ASCII字符n,u,l,l)。

     

否则,转换就像通过调用一样执行   没有参数的引用对象的toString方法;但如果   调用toString方法的结果为null,则字符串为“null”   而是用来代替。

答案 1 :(得分:1)

表达式

String s = "literal" + object;

编译到

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

如果我们查看StringBuilder#append(Object)的源代码,我们会发现:

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

如果我们查看String.valueOf(Object)的源代码,我们会发现:

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

最终,调用对象的toString()方法。

大肆诽谤DavidWallace的评论:

第15.18.1节陈述

  

...如果只有一个操作数表达式是String类型,则对另一个操作数执行字符串转换(第5.1.11节)以在运行时生成字符串。 ...

和第5.1.11节陈述

  

...执行转换就好像通过调用没有参数的引用对象的toString()方法一样;但是如果调用toString()方法的结果为null,则使用字符串“null”。 ...

所以看来当前的JDK 没有直接遵守JLS,但它最终会到达那里。

答案 2 :(得分:0)

这与this无关 与字符串一起使用时,Java的+运算符将在任何非字符串操作数上隐式调用toString()

这就是像"A" + 1这样的表达式的编译方式。

答案 3 :(得分:0)

在这一行:

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

运算符'+'使用两个字符串,java隐式调用toString()方法以获取此引用的对象的字符串表示形式。写“this”或“this.toString()”完全等效。