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