为什么即使没有调用它,也会引发A类中的toString?

时间:2017-03-27 10:06:51

标签: java string class tostring

public class Test {
    public static void main(String[] args) {
        Object a1 = new A();
        Object a2 = new Object();
        System.out.println(a1);
        System.out.println(a2);
    }
}

class A {
    int x;

    public String toString() {
        return "A's x is " + x;
    }
}

输出

  

A的x为0

     

java.lang.Object@1edf1c96

当打印a1时,调用A类中的toString()方法而不显式调用。你能告诉我这是怎么回事吗?

4 个答案:

答案 0 :(得分:1)

toString()隐式调用println(Object)。显然,因为它需要显示String,并且toString()保证为所有对象返回某种形式的String表示。

答案 1 :(得分:1)

正如您可以阅读PrintStream.println(Object)的文档:

  

<强> public void println(Object x)

     

打印一个对象,然后终止该行。这个   方法的行为就好像调用print(Object) 然后   println()

     

参数:
  x - 要打印的对象。

现在,如果我们看一下PrintStream.print(Object),我们会看到:

  

<强> public void print(Object obj)

     

打印对象。字符串由...生成   根据{{​​1}} 方法将其翻译为字节   平台的默认字符编码,并写入这些字节   完全按照String.valueOf(Object)方法的方式。

     

参数:
  write(int) - 要打印的对象

现在您可以看到,String.valueOf(object)在内部被调用,其定义为:

  

<强> obj

     

返回Object的字符串表示形式   参数。

     

参数:
  public static String valueOf(Object obj) - 一个对象   返回:
如果   参数为obj,然后是等于null的字符串; ,否则,   返回"null"的值。

这意味着,如果你写的东西如下:

obj.toString()

你实际上已经将等效的写成了:

System.out.println(foo);

进一步扩展为:

System.out.print(foo);
System.out.println();

扩展为:

System.out.print(String.valueOf(foo));
System.out.println();

或者说清楚一点。在if(foo == null) { System.out.print("null"); } else { System.out.print(foo.toString()); } System.out.println();的代码中,您会看到类似的内容:

PrintStream

public class PrintStream { // ... public void println(Object x) { this.print(x); this.println(); } public void print(Object obj) { String result = String.valueOf(obj); // ... do something with result (print it to the stream) } } 中你会找到类似的内容:

String

答案 2 :(得分:1)

toString()方法在每个Object中定义。它的默认行为是返回该对象的字符串表示形式,如"java.lang.Object@1edf1c96"

A类中,您刚刚用新的toString()方法取代了这种行为,重新定义了println()方法(&#34;重新定义&#34;意味着在使用相同的子类中再次定义该方法签名)。

这称为覆盖

当您打印对象时,toString()方法将盲目地调用对象的t3.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mStorageRef = FirebaseStorage.getInstance().getReference(); //Upload // //Download File localFile = null; try { localFile = File.createTempFile("file", "pdf"); } catch (IOException e) { e.printStackTrace(); } File storagePath = new File(Environment.getExternalStorageDirectory(), "directory_name"); if(!storagePath.exists()) { storagePath.mkdirs(); } final File myFile = new File(storagePath,"IBM2013507.pdf"); StorageReference riversRef = mStorageRef.child("IBM2013507.pdf"); riversRef.getFile(myFile) .addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() { @Override public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) { // Successfully downloaded data to local file Log.v("Download","Success"); // ...taskSnapshot } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception exception) { // Handle failed download Log.v("Download","unSuccess"); // ... } }); // } }); 方法,而不知道(或关心)它是否被重新定义。

答案 3 :(得分:1)

如果要将任何对象表示为字符串,toString()方法就会出现。

toString()方法返回对象的字符串表示形式。

如果打印任何对象,java编译器会在内部调用对象上的toString()方法。因此,覆盖toString()方法,返回所需的输出,它可以是对象的状态等取决于您的实现。

通过覆盖toString()类的Object方法,我们可以返回对象的值,因此我们不需要编写太多代码。