java重写toString方法

时间:2024-01-27 13:20:48

今天来谈一下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方法,从而看到类属性的详细信息。

如有疑问欢迎下方留言,感谢观看!