您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“怎么優雅地打印一個Java對象”,內容詳細,步驟清晰,細節處理妥當,希望這篇“怎么優雅地打印一個Java對象”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
提問者定義了這樣一個類:
public class Cmower { private String name; public Cmower(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
然后創建了一個該類的對象,并嘗試打印它:
Cmower cmower = new Cmower("沉默王二"); System.out.println(cmower);
但是輸出的結果并不是他想要的:
com.cmower.java_demo.stackoverflow.printObject.Cmower@355da254
除此之外,他在打印數組的時候也出現了相似的問題:
Cmower [] cmowers = {new Cmower("沉默王二"), new Cmower("沉默王三")}; System.out.println(cmowers);
輸出結果為:
[Lcom.cmower.java_demo.stackoverflow.printObject.Cmower;@4dc63996
Cmower@355da254 和 [LCmower;@4dc63996 這樣的輸出結果代表著什么意思呢?怎么樣才能把 Cmower 類的 name 打印出來呢?以及如何打印一個對象的列表(數組或者集合)呢?
如果大家也被這樣的問題困擾過,或者正在被困擾,就請隨我來,咱們肩并肩手拉手一起梳理一下這個問題,并找出優秀答案。Duang、Duang、Duang,打怪進階嘍!
01、究竟發生了什么?
所有的 Java 對象都默認附帶了一個 toString() 的方法,當我們嘗試打印這個對象的時候,該方法就會被調用。
System.out.println(object); // 調用 object.toString()
toString() 方法由 Object 類(所有 Java 對象的超類)定義,該方法會返回一個看起來晦澀難懂的字符串:
1)Class 名,由包名和類名組成,比如 com.Cmower;
2)@ 連接符;
3)十六進制的哈希碼。
來看一下該方法的源碼:
public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); }
數組和普通的 Java 對象類似,只有一點點不同——追蹤 Class 類的 getName()方法就可以印證這一點。
If this class object represents a class of arrays, then the internal form of the name consists of the name of the element type preceded by one or more '[' characters representing the depth of the array nesting.
大致的意思就是,如果是一個數組的話,Class 名的前面會有一個或者多個英文中括號“[”,表示數組的維度(一維數組為一個“[”,二維數組為兩個“[”),然后再緊跟一個元素的類型首字母。
這就是為什么對象數組的前綴是“[L”的原因。是不是有一種恍然大悟的感覺?
02、自定義輸出
如果想在打印的時候輸出自己預期的結果,就必須在自定義類中重寫 toString() 方法,來看例子。
public class Cmower { private String name; // 省略構造方法和 getter/setter @Override public String toString() { return name; } }
當我們再次打印 Cmower 對象時,輸出結果就不再是 com.Cmower@355da254 了。
沉默王二
但是這樣的結果并不會令我們滿意,它有些突兀,沒法表示對象的類型。更優雅的做法是這樣的:
public class Cmower { private String name; // 省略構造方法和 getter/setter @Override public String toString() { return getClass().getSimpleName() + "[name=" + name + "]"; } }
再次打印 Cmower 對象,輸出結果為:
Cmower[name=沉默王二]
這樣的形式不僅看起來美觀,還能夠在調試的時候給出有用的信息。但是,有時候我們不想重寫 toString() 方法(想保留原有的打印格式 ClassType@123121),又想打印該對象的信息,那么最好定義一個新的方法,比如說 toMyString() 方法。
03、自動化輸出
IDE(Eclipse 或者 Intellj IDEA) 通常會提供一種針對類的字段的輸出格式,用來覆蓋 toString() 方法。
@Override public String toString() { return "Cmower{" + "name='" + name + '\'' + '}'; }
另外,一些開源的第三方類庫也會提供這樣的功能,比如說:
1)Apache Commons Lang 的 ToStringBuilder。
使用方法:
@Override public String toString() { return ToStringBuilder.reflectionToString(this); }
輸出結果:
com.cmower.printObject.Cmower@355da254[name=沉默王二]
2)Google Guava 的 MoreObjects
使用方法:
@Override public String toString() { return MoreObjects.toStringHelper(this) .add("name", getName()) .toString(); }
輸出結果:
Cmower{name=沉默王二}
3)Lombok 的 @toString 注解(IDE 需要先安裝 Lombok 的插件)
使用方法:
@ToString public class Cmower { private String name; // 省略構造方法和 getter/setter }
只需要一個 @toString 注解,不需要覆蓋 toString() 方法。
輸出結果:
Cmower(name=沉默王二)
04、打印對象列表(數組或者集合)
上述內容已經把打印單個對象的事情嘮明白了,are you ok?接下來,我們來說道說道打印對象列表的事兒。
1)數組
Arrays.toString() 可以將任意類型的數組轉成字符串,包括基本類型數組和引用類型數組。代碼示例如下。
Cmower[] cmowers = {new Cmower("沉默王二"), new Cmower("沉默王三")}; System.out.println(Arrays.toString(cmowers));
輸出結果:
[Cmower{name='沉默王二'}, Cmower{name='沉默王三'}]
2)集合
對于集合來說,可以直接打印就能輸出我們預期的結果。代碼示例如下。
List<Cmower> list = new ArrayList<>(); list.add(new Cmower("沉默王二")); list.add(new Cmower("沉默王三")); System.out.println(list);
輸出結果:
[Cmower{name='沉默王二'}, Cmower{name='沉默王三'}]
讀到這里,這篇“怎么優雅地打印一個Java對象”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。