怎麼正确的在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]