Object类引入
类 Object 是类层次结构的根类,每个类都使用 Object 作为超类。
所有对象(包括数组)都可以调用到Object中的方法;
Object类中方法
1. int hashCode() 返回对象的哈希码值。
2. boolean equals(Object obj) 根据实际业务,判断两个对象是不是“相等”,不是直接判断==
判断当前对象和obj参数是否"相等",要比较什么类型的对象就用重写其对应类型的equals方法
例如:
两个学生,我们认为姓名和电话号码相同就是同一个人,就用重写学生类的equals方法
两个教师,我们认为身份证号相同就是同一个人,就用重写教师类的equals方法
3. String toString() 返回对象的字符串表示形式。如果需要打印对象的制定格式,则需要重写当前对象所对 应类的toString方法即可
4. Class getClass() 返回此 Object的运行时类,即当前对象所对应的字节码文件
(反射时重点讲)字节码文件用==比较(了解)
toString方法
直接打印对象:结果是地址
|
为什么呢?通过代码跟踪得到下图调用关系
代码跟踪如下:
所以,只要将User类的toString方法重写,只可以打印制定格式
实例代码:
/**
* 需求:希望打印对象的时候是指定格式:
[隔壁老王,9969]
[name的值,phoneNumber的值]
就需要重写当前Student类的toSting方法
*/
@Override
public String toString() {
return "[" + name + "," + phoneNumber + "]";
}
equals:
有如下需求:两个学生,我们认为姓名和电话号码相同就是同一个人,就用重写学生类的equals方法
equals比较结果是:false 为什么呢?因为没有重写equals方法,默认是继承Object中的equals方法,==比较
所以必须根据现实需求重写equals方法:
/**
* 这里因为还没有学习多态,所以将形参Object写成Student,再将@Override删除
*
* 比较引用类型一般用equals比较。 ==是比较的地址
* 而这里,我们只需要比较String对象中的值即可
* this.name是String类型,比较String类型的值用String的equals方法
*/
//public boolean equals(Object obj) {这里因为还没有学习多态,所以将形参Object写成Student,再将@Override删除
public boolean equals(Student stu) {
//需求:两个学生,我们认为姓名和电话号码相同就是同一个人,
就用重写学生类的equals方法
//要比较两个引用类型的值,就用该引用类型的equals方法,
这里this.name是String的equals方法。
并且String的equals方法已经重写了
if (this.name.equals(stu.name) && this.phoneNumber.equals(stu.phoneNumber)) {
return true;
}
return false;
}
重写方法后的完整代码如下:
/**
* 学生类
*/
public class Student {
private String name;
private String phoneNumber;
int age;
public Student() {
}
public Student(String name, String phoneNumber) {
this.name = name;
this.phoneNumber = phoneNumber;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
/**
* 需求:希望打印对象的时候是指定格式:[隔壁老王,9969] [name的值,phoneNumber的值]就需要重写当前Student类的toSting方法
*/
@Override
public String toString() {
return "[" + name + "," + phoneNumber + "]";
}
/**
* 这里因为还没有学习多态,所以将形参Object写成Student,再将@Override删除
*
* 比较引用类型一般用equals比较。 ==是比较的地址
* 而这里,我们只需要比较String对象中的值即可
* this.name是String类型,比较String类型的值用String的equals方法
*/
// public boolean equals(Object obj) {这里因为还没有学习多态,所以将形参Object写成Student,再将@Override删除
public boolean equals(Student stu) {
//需求:两个学生,我们认为姓名和电话号码相同就是同一个人,就用重写学生类的equals方法
//要比较两个引用类型的值,就用该引用类型的equals方法,这里this.name是String的equals方法。并且String的equals方法已经重写了
if (this.name.equals(stu.name) && this.phoneNumber.equals(stu.phoneNumber)) {
return true;
}
return false;
}
}
测试代码:
public class StudentTest {
public static void main(String[] args) {
Student stu1 = new Student("隔壁老王","9969");
Student stu2 = new Student("隔壁老王","9969");
//1. 调用Object继承过来的hashCode方法
System.out.println("stu1的哈希值:"+stu1.hashCode());//366712642
System.out.println("stu2的哈希值:"+stu2.hashCode());//1829164700
//2. 打印对象是地址:特点(全限定包名+@+对象的哈希码的十六进制)
//需求:希望打印对象的时候是指定格式:[隔壁老王,9969] [name的值,phoneNumber的值]就需要重写当前Student类的toSting方法
System.out.println(stu1);//cn.qjzx.object.Student@15db9742
System.out.println(stu2);//cn.qjzx.object.Student@6d06d69c
//3. boolean equals(Object obj) 根据实际业务,判断两个对象是不是“相等”,不是直接判断==
//需求:两个学生,我们认为姓名和电话号码相同就是同一个人,就用重写学生类的equals方法
System.out.println(stu1.equals(stu2));//判断stu1对象是否和stu2对象相等。如果相等则是true,否则是false
//4. Class getClass() 返回此 Object的运行时类,即当前对象所对应的字节码文件 (反射最常用)字节码文件用==比较(了解)
Class<? extends Student> clazz = stu1.getClass();
System.out.println(clazz);//class cn.qjzx.object.Student
Class<? extends Student> clazz2 = stu2.getClass();
System.out.println(clazz2);//class cn.qjzx.object.Student
//字节码文件是否相等用==判断
System.out.println(clazz == clazz2);//true
}
}
== 和 equals区别
== :
比较基本数据类型: 比较的就是值是否相等;
比较引用数据类型: 比较的是对象的地址是否相等
equals 只能用于引用类型
根据实际业务比较两个对象是否相等。默认是不重写是==比较。在实际开发中,我们一般比较对象都是通过对象的属性值进行比较(一般比较对象的地址没有多大用处),所以我们会覆写Object中的此方法,把自己的判断机制写在方法里面;