怎么正確的在JAVA中打印一個對象?而不是輸出SomeType@2f92e0f4?
我們有下面一個類:
class SomeClass {
private String field;
...getter/setter
}
當(dāng)我們嘗試直接輸出該類的時候:
System.out.println(someClass);
會得到一個奇怪的結(jié)果:
org.xiaochao.SomeClass@4e50df2e
為什么會得到這樣的結(jié)果呢?怎么才能正常的輸出呢?
為什么會得到一個奇怪的結(jié)果
事實上,java的每個類都是繼承自Object的,Object中有幾個方法,其中一個方法是toString(),System.out.println被調(diào)用時,會自動調(diào)用對象的toString()方法。如果我們的類覆蓋了該方法,就會調(diào)用我們實現(xiàn)的結(jié)果,如果未覆蓋,則會調(diào)用Object的該方法。
Object實現(xiàn)的toString()方法如下所示:
public String toString() {
return getClass().getName() +
"@" + Integer.toHexString(hashCode());
}
因此,我們得到的輸出org.xiaochao.SomeClass@4e50df2e是Object的默認(rèn)實現(xiàn):
-
org.xiaochao.SomeClass是getClass().getName()得到的類名稱。會帶著包名 -
@是中間的連接符 -
4e50df2e是當(dāng)前實例的hashCode
如何正確輸出對象
自定義toString來輸出對象
想要自定義輸出對象的內(nèi)容,我們需要實現(xiàn)toString()方法才行,比如說:
class SomeClass {
private String field;
@Override
public String toString() {
return "field: " + field;
}
}
這樣就可以得到一個比較好看的結(jié)果了:
field: myfield value
輸出對象更好的方法
當(dāng)類的數(shù)量比較多,或者是屬性比較多時,自行手寫toString()就很麻煩了,這里介紹幾個簡單的方法。
通過idea自動生成
idea可以自動生成類的toString方法,鼠標(biāo)放到類里面,按住Alt+Insert,在彈出的窗口選擇toString(),選擇要輸出的字段,就可以一鍵生成了。
生成結(jié)果如下:
@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;
}
輸出結(jié)果:
SomeClass(field=myfield value)
可以看到效果也是很不錯的。
使用commons-lang3工具輸出對象
Apache Commons-lang3 提供了非常多的實用工具。當(dāng)我們拿到一個不是我們自己寫的類時,可以通過它的反射工具ReflectionToStringBuilder直接打印出來對象的值,而且還可以打印對象中的對象的值。
在maven中添加依賴:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
使用:
ReflectionToStringBuilder.toString(someClass)
輸出結(jié)果:
SomeClass@37bba400[field=myfield value]