天天看點

怎麼正确的在JAVA中列印一個對象,而不是輸出Some@2f92e0f4?

作者:小朝的程式設計生涯

怎麼正确的在JAVA中列印一個對象?而不是輸出SomeType@2f92e0f4?

我們有下面一個類:

class SomeClass {
    private String field;
    ...getter/setter
}
           

當我們嘗試直接輸出該類的時候:

System.out.println(someClass);
           

會得到一個奇怪的結果:

org.xiaochao.SomeClass@4e50df2e
           

為什麼會得到這樣的結果呢?怎麼才能正常的輸出呢?

為什麼會得到一個奇怪的結果

事實上,java的每個類都是繼承自Object的,Object中有幾個方法,其中一個方法是toString(),System.out.println被調用時,會自動調用對象的toString()方法。如果我們的類覆寫了該方法,就會調用我們實作的結果,如果未覆寫,則會調用Object的該方法。

Object實作的toString()方法如下所示:

public String toString() {
        return getClass().getName() +
         "@" + Integer.toHexString(hashCode());
    }
           

是以,我們得到的輸出org.xiaochao.SomeClass@4e50df2e是Object的預設實作:

  • org.xiaochao.SomeClass 是 getClass().getName() 得到的類名稱。會帶着包名
  • @是中間的連接配接符
  • 4e50df2e是目前執行個體的hashCode

如何正确輸出對象

自定義toString來輸出對象

想要自定義輸出對象的内容,我們需要實作toString()方法才行,比如說:

class SomeClass {
    private String field;

    @Override
    public String toString() {
        return "field: " + field;
    }
}
           

這樣就可以得到一個比較好看的結果了:

field: myfield value
           

輸出對象更好的方法

當類的數量比較多,或者是屬性比較多時,自行手寫toString()就很麻煩了,這裡介紹幾個簡單的方法。

通過idea自動生成

idea可以自動生成類的toString方法,滑鼠放到類裡面,按住Alt+Insert,在彈出的視窗選擇toString(),選擇要輸出的字段,就可以一鍵生成了。

生成結果如下:

@Override
public String toString() {
    return "SomeClass{" +
            "field='" + field + '\'' +
            '}';
}
           

通過lombok生成

lombok非常強大,可以通過添加注解的方式直接生成toString()。

在maven中添加依賴:

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.24</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
           

在代碼中使用:

import lombok.ToString;

@ToString
class SomeClass {
    private String field;
}
           

輸出結果:

SomeClass(field=myfield value)
           

可以看到效果也是很不錯的。

使用commons-lang3工具輸出對象

Apache Commons-lang3 提供了非常多的實用工具。當我們拿到一個不是我們自己寫的類時,可以通過它的反射工具ReflectionToStringBuilder直接列印出來對象的值,而且還可以列印對象中的對象的值。

在maven中添加依賴:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version>
</dependency>
           

使用:

ReflectionToStringBuilder.toString(someClass)
           

輸出結果:

SomeClass@37bba400[field=myfield value]