如何优雅地打印一个Java对象?

本文详细解释了Java对象默认toString方法的工作原理,如何自定义输出格式,以及如何利用ApacheCommonsLang和GoogleGuava库进行自动化输出。作者还分享了解决打印对象和数组时困惑的方法。
摘要由CSDN通过智能技术生成

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=沉默王二}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

看完上述知识点如果你深感Java基础不够扎实,或者刷题刷的不够、知识不全面

小编专门为你量身定制了一套<Java一线大厂高岗面试题解析合集:JAVA基础-中级-高级面试+SSM框架+分布式+性能调优+微服务+并发编程+网络+设计模式+数据结构与算法>

image

针对知识面不够,也莫慌!还有一整套的<Java核心进阶手册>,可以瞬间查漏补缺

image

全都是一丢一丢的收集整理纯手打出来的

更有纯手绘的各大知识体系大纲,可供梳理:Java筑基、MySQL、Redis、并发编程、Spring、分布式高性能架构知识、微服务架构知识、开源框架知识点等等的xmind手绘图~

image

image
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

针对知识面不够,也莫慌!还有一整套的<Java核心进阶手册>,可以瞬间查漏补缺

[外链图片转存中…(img-M9I32CXl-1713632226698)]

全都是一丢一丢的收集整理纯手打出来的

更有纯手绘的各大知识体系大纲,可供梳理:Java筑基、MySQL、Redis、并发编程、Spring、分布式高性能架构知识、微服务架构知识、开源框架知识点等等的xmind手绘图~

[外链图片转存中…(img-F5AuBFys-1713632226699)]

[外链图片转存中…(img-wxZPgx6W-1713632226699)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 8
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值