toString运行方式
为什么输出对象名能够直接输出对象地址值或重写toString方法后直接输出成员变量
查询API文档发现System.out.println();存在于PrintStream类中
println
public void println(String x)
打印一个字符串,然后终止行。 该方法的行为就像调用print(String)
,然后是println()
一样 。
public void println(Object x)
打印一个对象,然后终止该行。 此方法首先调用String.valueOf(x)来获取打印对象的字符串值,然后表现为调用print(String)
然后println()
。
-
参数
x
- 要打印的Object
。
所以我们打印对象时用的是第二个println()
这里创建一个Person类然后重写toString()
方法进行测试
- 重写方法
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
- 测试类
public class Test {
public static void main(String[] args) {
//创建一个Person对象
Person r=new Person("张三",23);
//直接打印
System.out.println(r);
//执行toString方法
System.out.println(r.toString());
}
打印结果相同
Person{name='张三', age=23}
Person{name='张三', age=23}
但两者使用的println()
方法不同
System.out.println(r.toString());
使用的是下面的方法
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
System.out.println(r);
使用的是下面方法
public void println(Object x) {
String s = String.valueOf(x);
synchronized (this) {
print(s);
newLine();
}
}
这里传进来的是r,然后执行valueof()
方法
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
这里的obj还是r
也就是说这里的返回值是r.toString()
;然后打印
和上面的相同,也就多了一个将对象转成字符串的方法,因为所有类都默认继承Object这个类,所以会返回一个地址值
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
对该方法重写就可以打印了
equals
同理所有类都继承Object这个类
它内部的equals方法是
public boolean equals(Object obj) {
return (this == obj);
}
可以看到是直接比较的是对象的地址值,而equals()
是比较内容是否相同的
所以也要对此重写,还拿上面Person示例
- 重写方法
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
if (age != person.age) return false;
return name.equals(person.name);
}
这里创建了两个继承Person类的Student类和Teacher类
- 测试类
public class Test {
public static void main(String[] args) {
Person r=new Person("张三",23);
Person r2=new Person("张三",23);
System.out.println(r.equals(r2));
Person stu=new Student("张三",18);
Person tea=new Teacher("张三",18);
System.out.println(stu.equals(tea));
}
}
测试结果
true
false
执行原理就是先判断俩对象地址值是否相同,相同自然是true,不相同话就在比较对象不为空的情况下判断是否为同一类型的对象,相同就进行转型,然后判断内容是否相等