java输出成员基本信息_Java打印对象信息(一)

在日常开发中,我们总需要打印日志,记录程序中一些关键对象的信息,大大提高bug的排查速度。但是如果类的设计不规范,这些类的对象信息是不能被Log框架或者System.out.println()语句规范地打印出来的。比如下面这个Person类,这种只有成员变量以及成员变量的get/set函数的类,常被用作VO、DTO、DO等,如果直接按照以下方式,其对象信息打印出来对日志分析基本没有用处。(本文代码运行环境采用JDK版本为JDK9)

《一》采用System.out.println()方式打印对象信息:

public class Person {

private int age;

private String name;

public Person(){

}

public Person(int age, String name) {

this.age = age;

this.name = name;

}

public static void main(String []args){

Person p = new Person(22,"Allen");

Person p1 = new Person(18,"Peter");

System.out.println(p);

System.out.println(p1);

}

}

我们看一下输出结果:

Person@64c64813

Person@3ecf72fd

可见根本没有打印出我们想看到的对象p的成员变量信息,这个打印结果是怎么来的呢?我们先看一下System.out.println()的内部实现(java.io.PrintStream类):

public void println(Object x) {

String s = String.valueOf(x);

synchronized (this) {

print(s);

newLine();

}

}

可以看出先是打印String.valueOf(x)的信息,然后再打印一个换行,而String.valueOf(x)的内部实现如下:

/**

* Returns the string representation of the {@code Object} argument.

*

* @param obj an {@code Object}.

* @return if the argument is {@code null}, then a string equal to

* {@code "null"}; otherwise, the value of

* {@code obj.toString()} is returned.

* @see java.lang.Object#toString()

*/

public static String valueOf(Object obj) {

return (obj == null) ? "null" : obj.toString();

}

如果对象为null就返回字符串null,否则返回这个对象的toString()函数的结果,我们需要注意toString()这个函数是定义在Object类中的,其在Object类中的定义如下:

/**

* Returns a string representation of the object. In general, the

* {@code toString} method returns a string that

* "textually represents" this object. The result should

* be a concise but informative representation that is easy for a

* person to read.

* It is recommended that all subclasses override this method.

*

* The {@code toString} method for class {@code Object}

* returns a string consisting of the name of the class of which the

* object is an instance, the at-sign character `{@code @}', and

* the unsigned hexadecimal representation of the hash code of the

* object. In other words, this method returns a string equal to the

* value of:

** * getClass().getName() + '@' + Integer.toHexString(hashCode())

*

*

* @return a string representation of the object.

*/

public String toString() {

return getClass().getName() + "@" + Integer.toHexString(hashCode());

}

从中我们不难看到每个类如果没有重写toString()函数的话,默认是返回该类的名称 + “@” + 该对象hashCode值得十六进制数字;所以JDK官方是推荐我们所有的类都应该重写此类(It is recommended that all subclasses override this method.)。如果我们在上面的Person类中重写该方法,那么System.out.println语句就会按照我们的重写的toString()方法打印对象信息,如下:

public class Person {

private int age;

private String name;

public Person() {

}

public Person(int age, String name) {

this.age = age;

this.name = name;

}

@Override

public String toString() {

return "Person(age:" + age + ",name:" + name + ")";

}

public static void main(String[] args) {

Person p = new Person(22, "Allen");

Person p1 = new Person(18, "Peter");

System.out.println(p);

System.out.println(p1);

}

}

输出结果:

Person(age:22,name:Allen)

Person(age:18,name:Peter)

这样就可以清晰地打印出每个Person对象的成员信息了。

如果你使用了Lombok插件,那么直接使用它的@Data注解,无需实现toString()函数的复写了,如下:

import lombok.Data;

@Data

public class Person {

private int age;

private String name;

public Person() {

}

public Person(int age, String name) {

this.age = age;

this.name = name;

}

public static void main(String[] args) {

Person p = new Person(22, "Allen");

Person p1 = new Person(18, "Peter");

System.out.println(p);

System.out.println(p1);

}

}

代码运行结果:

Person(age=22, name=Allen)

Person(age=18, name=Peter)

这里使用的Lombok插件版本为1.16.10,可以看出插件帮我们完成了对一个对象的描述功能。如果我们既使用了Lombok插件,又自己重写了一下toString()函数,会有什么的情况呢?我们试一下:

import lombok.Data;

@Data

public class Person {

private int age;

private String name;

public Person() {

}

public Person(int age, String name) {

this.age = age;

this.name = name;

}

@Override

public String toString() {

return "年龄:" + age + ";名字:" + name;

}

public static void main(String[] args) {

Person p = new Person(22, "Allen");

Person p1 = new Person(18, "Peter");

System.out.println(p);

System.out.println(p1);

}

}

输出结果为:

年龄:22;名字:Allen

年龄:18;名字:Peter

可以看到打印信息使用的是我们重写的toString()方式,具体Lombok插件是如何实现的,大家感兴趣可以看一下Lombok的实现机制。

本次主要讲了System.out.println()这种最基础的的方式打印对象信息需要注意的地方,主要就是toString()函数,下一节我们看一下一些日志框架(例如log4j等)是如何实现对象信息的打印效果的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值