Java中打印对象输出的字符串到底是什么
前言
我们在进行 Java 编程时,经常要打印对象,有的是查看是否拿到了该对象,有的是查看该对象中的数据。打印输出的却是一知半解的字符串,那么这个字符串是怎么来的?代表什么?我们如何打印出对象中的数据呢?
一、Java中打印对象
1.演示代码
我们使用 Java 的 System.out
类可以打印输出对象,例如我们有一个 Student
类,有三个成员变量,一个有参构造方法,它的代码如下:
点击查看代码
public class Student {
private String name;
private String sex;
private Integer age;
public Student(String name, String sex, Integer age) {
this.name = name;
this.sex = sex;
this.age = age;
}
}
然后我们新建测试类,创建 Student
对象,并直接使用 System.out.println
语句进行打印。
点击查看代码
public class Test {
public static void main(String[] args) {
Student student = new Student("张三", "男", 16);
System.out.println(student);
}
}
执行结果如下:
点击查看代码
com.example.Student@2f4d3709
2.提出问题
通过演示代码运行结果可以看到打印输出的是当前包下的类名,还有@
字符,还有一串数字和字母。打印出类名很好理解,但是@
、数字、字母是什么意思呀?应该很多同学都不是很明白吧。
二、深入分析
1.打印的字符串是什么
当我们在 Java 中使用 System.out.println
或者其他输出语句时,如果传入的参数不是字符串类型的数据,那么程序会自动调用该数据所属类的 toString()
方法。目前 Student
类中并没有 toString()
方法呀,是所有 Java 类都直接或间接继承了 Object
类,而 Object
类中有一个默认的 toString()
方法,代码如下:
点击查看代码
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
该方法官方注释如下:
该方法返回对象的字符串表示形式。一般来说,toString 方法返回一个“文本表示”此对象的字符串。结果应该是一个简洁但信息丰富的表示,便于人们阅读。建议所有子类重写此方法。
Object 类的 toString 方法返回一个字符串,该字符串由该对象作为其实例的类的名称、@符号字符’ @'以及该对象哈希码的无符号十六进制表示形式组成。换句话说,这个方法返回的字符串等于的值:getClass().getName() + ‘@’ + Integer.toHexString(hashCode())
也就是我们的 Student
没有重写 toString()
方法,而是自动调用了 Object
类中的 toString()
方法。这时候我们打印输出的是一个字符串,其中包含对象的类名和哈希码。
2.是对象的地址吗?
有时候我们总是说打印了该对象的地址,其实是不准确的。打印的内容一个是类名,一个是哈希码。打印的对象的哈希码并不是引用地址,尽管在某些情况下它们可能看起来像是一样的。
哈希码是一个整数,它是由Java运行时环境根据对象的内部状态计算出来的。对于一个类的任何两个不同的实例,它们的哈希码通常不会相同。也就是说,如果在打印一个对象时,看到了两个不同的哈希码,可以确定这两个对象是不同的,它们占用不同的内存空间。
而引用地址是内存中的一个地址值,它表示某个对象在内存中的位置。对于同一个对象,无论它被引用多少次,它的引用地址始终是相同的。两个不同的对象的引用地址也是不同的。
通常情况下,打印一个 Java 对象时显示的是该对象的字符串表示,这个字符串既包括了实例的哈希码,也包括了它的一些其他信息。因此,在某些情况下,打印出来的哈希码和引用地址可能看起来相同,但实际上它们是不同的概念。
三、打印对象内部信息
如何打印对象内部信息呢,比如打印出对象中姓名、性别和年龄。这时需要我们自定义或是重写 Student
类的 toString()
方法。如下代码中我们重写 toString()
方法:
点击查看代码
public class Student {
private String name;
private String sex;
private Integer age;
public Student(String name, String sex, Integer age) {
this.name = name;
this.sex = sex;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
'}';
}
}
我们再次执行 Test
中的 main()
方法,可得结果如下:
点击查看代码
Student{name='张三', sex='男', age=16}
这时就调用了被重写的 toString()
方法,并按照我们的意愿对 student
对象进行了打印输出。
总结
这里我们知道了 Java 中打印对象,如果没有重写 toString()
方法,那么调用执行的是 Object
类中的 toString()
方法,会打印该对象的类名和哈希码,而它的哈希码也不是对象的地址。如果想更好的输出对象信息,可以重写 toString()
方法。