今天来谈一下java中toString这个方法。
在初学java的时候,我们学的第一个程序大概都是这样的:
public static void main(String[] args) {
System.out.println("Hello,world!");
}
可以已经写得不厌其烦了,哈哈,但是大家想过没有,假如我直接输出一个对象会怎么样呢?
private String name;
private int age;
public Test(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Test test = new Test("张三",18);
System.out.println(test);
}
结果:com.zhang.Test@2503dbd3
乍一看,这是个啥?
实际啊,这是由于我们没有重写Object类的toString方法,导致它输出的是一些古怪的字符串(该对象的内存地址)。
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
通过源码我们可以看到它是一个由类名+@符号+对象哈希码的无符号十六进制表示组成。
getClass()是得到一个Class对象,getName()则是 得到这个类的名称。
当我们在该类重写toString方法之后,它的结果又不一样了
private String name;
private int age;
@Override
public String toString() {
return "name=\'" + name + \'\\'\' + ", age=" +age;
}
public Test(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Test test = new Test("张三",18);
System.out.println(test);
}
结果:name=\'张三\', age=18
这就是重写toString之后的好处,我们可以清晰的看到对象的属性以及它的值。应用也十分广泛,在平常学习中,我们常常想知道代码的正确性以及赋值成功与否,就可以直接打印这个类,在控制台我们可以清晰的看到数据,不重写则只是一串内存地址。
大家可能还有一个疑惑,就是为什么我没有调用toString方法,但是他却输出了呢?会不会是自动调用toString方法呢?
肯定不是自动调用。答案如下:
//println方法的源码
public void println(Object x) {
String s = String.valueOf(x);//这里调用了valueof方法
synchronized (this) {
print(s);
newLine();
}
}
//valueOf方法的源码
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
因为Object类是所有类的父类,所以当我们传入一个Test类的一个对象test的时候,它会自动向上转型为Object类。下面的三目运算符可以看出来,返回的是obj.toString(),当我们没重写toString的时候它就会调用Object类的toString方法,也就是返回内存地址,由于Test类重写了toString方法,所以它会调用重写之后的toString方法,从而看到类属性的详细信息。
如有疑问欢迎下方留言,感谢观看!