【Java】`toString()`

一、用法

toString() 方法其实很好理解。to:变成,String:字符串,合在一起就是:变成字符串。

public String toString()				//返回该对象的字符串表示形式(可以看做是对象的内存地址值)

代码示例

Object obj = new Object();
String str1 = obj.toString();
System.out.println(str1); // java.lang.Object@119d7047

程序运行完毕,可以发现它把对象变成了这种字符串:java.lang.Object@119d7047

这种字符串它其实是有规律的,可以分成三段,以中间的 @ 为中心:前面是 包名 + 类型@ 自己本身是一个固定格式,@ 后面的一堆就是对象的地址值。

如果我创建的不是 Object类 的对象,而是其他类的对象,其实也是这样的。

Student.java

public class Student {
    private String name;
    private int age;

    // 无参构造、有参构造、get、set方法
}

注意这里,我没有让 Student 去继承其他的类,因此它默认就继承 Object。

运行下面代码,可以发现它也是这种 包名 + 类名 @ 对象地址值

Student stu = new Student();
String str2 = stu.toString();
System.out.println(str2);//com.itheima.a04objectdemo.student@4eec7777

这里我可以简单带大家去看一下 Object 的源代码。

选中 Object类名 ctrl + b 跟进,再按快捷键ctrl + F12 搜一下 toString() 然后回车。

image-20240421181741089

1、中间的 @ 是固定格式

2、前面的 getClass().getName() 就可以获取它的 包名 + 类名

3、后面的 Integer.toHexString(hashCode()); 就可以获取到 对象的地址值

但是这个地址值获取到不是直接给你的,而是经过一系列的复杂运算,然后将它变成 16进制

但是现在我们可以把 Integer.toHexString(hashCode()) 简单的理解成是 对象的地址值

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

再往下可以去跟大家说一个小小的细节:

如果在打印 stu 的时候没有去调用 toString() 方法,而是直接打印一个对象。

你就会发现,你看到的效果其实是一样的

Student stu = new Student();
String str2 = stu.toString();
System.out.println(str2);//com.itheima.a04objectdemo.student@4eec7777

//细节:
System.out.println(stu);//com.itheima.a04objectdemo.student@4eec7777

那为什么是这样的呢?这时我就带着你去认识一下输出语句。


二、输出语句

输出语句 System.out.println() 分为三部分:

1、System:我们刚刚学习过,它是Java里面的一个类名

选择 System类名ctrl + b 跟进,往下找,可以发现:outSystem类 中的一个静态变量

因此在代码中,我们就可以通过类名直接调用静态变量 System.out

out 的初始值是 null,但是在下面会给 out 赋值。

out 的类型是 PrintStream,这个类在我们后面学习 IO流 的时候会再次细说。

现在我们可以先简单理解 System.out 就是:类型.静态变量,这样它就可以获取到打印的对象

image-20240421182434812

获取到 打印的对象 后,就可以用这个对象,去调用 println() 方法,方法里面的参数就表示我们要打印的内容。

我们可以选中这里的 println()ctrl + b 看下源码:

image-20240421183017348

如果你传递了一个对象进来,首先它会调用 String类 中的 valueOf() 静态方法,把对象传递进去

String s = String.valueOf(x);

valueOf() 是一个关键点,ctrl + b 跟进,可以看见它在底层做了一个这样的判断:判断对象为不为空,如果为空,返回字符串 "null,如果不是空,就会使用对象去调用 toString() 方法,即将对象变成了:包名 + 类名 + @ + 地址值 的形式。

image-20240421183242855

ctrl + alt + ← 回到上一步,因此方法的第一行其实就是将传递过来的对象变成了字符串,在底层调用了 toString() 方法。

有了这个字符串后,下面它就会去调用其他的方法将这个字符串打印出来。

image-20240421183455982

选中 writeln() 方法跟进,这个方法里面其实是有两个核心点的:

720行:textOut.write(s); 其实就是将对象的字符串进行打印

721行:textOut.newLine(); 其实就是做了一个换行处理

这些其实就是输出语句的核心逻辑

image-20240421183657204

总结:当我们打印一个对象的时候,底层会调用对象的 toString() 方法,把对象变成字符串,然后再打印在控制台上,打印完毕后换行处理。


三、引出 重写toString()方法

知道这个结论后,就需要思考了:

默认情况下因为 Object类 中的 toString() 方法返回的是地址值。所以默认情况下打印一个对象打印的就是地址值。

但是地址值对我来讲是没有意义的,如果我不想看到地址值,而是看到对象内部的属性值,那应该怎么办呢?

在之前我们学习继承的时候曾经说过:父类里面的方法如果不能满足当前的要求,就可以重写该方法。

解决办法:重写父类中的 toString() 方法即可。

当我直接在 Student类 中写 toString() 时,选择第二个 toString()

image-20240421185312305

然后回车,此时IDEA就会问你:你要不要将两个对象的属性值拼在里面?

image-20240421185452256

但是它的这种拼接方式,稍微有一点难。

image-20240421185554201

这里我将它改写一下,这样子看上去就非常的清爽了。

public String toString() {
    return name + ", " + age;
}

现在我已经对 toString() 方法进行了重写,那此时我再次打印 stu变量 的时候,它显示的还是地址值吗?

程序运行完毕,可以发现它打印的就是对象内部的属性值。

Student stu = new Student("张三", 23);
System.out.println(stu); // 张三, 23

四、快捷方式

其实这个书写的代码不需要我们自己去写,之前跟大家分享过 Ptg 插件,我们可以用 Ptg 自动去完成。

当我们写完私有化成员变量后,下面直接右键 ——> Ptg To JavaBean

image-20240421190220469

往下滑,可以发现插件自动帮我们拼接好了。

image-20240421190300367

回到测试类中,右键Run

Student stu = new Student("张三", 23);
System.out.println(stu); // Student{name = 张三, age = 23}

五、总结

如果我们打印一个对象,想要看到属性值的话,那么就重写 toString() 方法即可。

在重写的方法中把对象的属性进行拼接即可。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值