1、toString() 方法
(1)源码
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
(2)此方法默认实现
类名@对象的内存地址转化为十六进制。
int[] arr = {1, 2, 3, 4};
System.out.println(arr.toString()); // [I@27716f4
(3)设计目的
通过调用这个方法,可以将一个java对象转化成字符串的表现形式,建议所有子类都重写toString()方法。
(4)字符串中的equals方法
在java中,除了字符串中的equals方法,其他的类型如果想调用toString方法那么需要重写。
字符串中的toString方法的源码:
public String toString() {
return this;
}
2、equals() 方法
(1)设计初衷
判断两个对象是否相等
(2)Object中的equals源码
源码中还是用的 == 比较的是两个对象内存地址是否相同,如果我们只想单纯的比较两个对象的值是否相等,此方法就无法判断了,所以需要子类重写equals() 方法,注意重写的规则需要自己规定。
public boolean equals(Object obj) {
return (this == obj); // this代表调用equals方法的对象
}
(3)小例子
new 两个Time类,我们用equals()方法来判断,输出结果为:false
public class Test {
public static void main(String[] args) {
Time time1 = new Time(2021, 6, 7);
Time time2 = new Time(2021, 6, 7);
System.out.println(time1.equals(time2)); // false
}
}
class Time {
int year;
int month;
int day;
public Time(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
}
重写Object上的equals() 方法,此时在调用equals() 方法时,输出为:true
下边类型强转有一个特别值得注意的地方:向下转化(有父类型转化为子类型)强转前,必须要判使用instanceof 。
class Time {
int year;
int month;
int day;
public Time(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
// 【方式一】:方式一效率很低
// 重写Object上的 equals() 方法
@Override
public boolean equals(Object obj) {
// 这里之所以要强转为Time类型,原因传入的obj是Object类型的,而Object上边
// 没有year、month、day变量,所以需要强转,而强转的前提必须要判断:强转的
// 对象是否是强转的类的实例,否则如果不是的话会报错。
if (obj instanceof Time) {
Time t = (Time) obj;
if (this.year == t.year && this.month == t.month && this.day == t.day) {
return true;
}
}
return false;
}
// 【方式二】:相比方式一来说下边写法效率更高一些。
@Override
public boolean equals(Object obj) {
// 如果obj为null或者不是Time的实例直接返回false
if((obj == null) || !(obj instanceof Time)) {
return false;
}
// 基本类型或者字符串,内存地址相同
if(obj == this) {
return true;
}
Time t = (Time) obj;
if((this.year == t.year) && (this.month == t.month) && (this.day == t.day)) {
return true;
}
return false;
}
}
(4)扩展
在java工具类下的Date时间类中,new Date() 时调用equals( ) 来判断两个对象是否相等,输出结果为:true,原因是Date源码中重写了equals() 类
import java.util.Date;
public class Test {
public static void main(String[] args) {
Date d1 = new Date();
Date d2 = new Date();
System.out.println(d1.equals(d2)); // true
}
}
源码分析:
它会先判断传入的对象是否是Data实例,如果是的话,会调用Data实例对象上的getTime( ) 方法,判断两个时间戳是否相等。
public boolean equals(Object obj) {
return obj instanceof Date && getTime() == ((Date) obj).getTime();
}
(5)字符串中的equals() 方法重写了Object上的equals方法,所以比较两个字符串是否相等,需要使用equals() ,不能使用 ==
public class Test {
public static void main(String[] args) {
String a = new String("123");
String b = new String("123");
System.out.println(a == b); //false 比较的是内存地址
System.out.println(a.equals(b)); // true 因为重写了equals方法,所以不管你是否new输出的是true
}
}
总结
java中基本数据类型使用== 比较,而引用类型使用equals() 方法比较。