Object类
本文章为个人“Java零基础实战”学习笔记,仅供参考学习,侵权删
Object 就是 Java 提供的一个类,位于 java.lang 包中,该类是所有类的直接父类或间接父类。无论是 Java 提供的类,还是开发者自己定义的类,都是 Object 的直接子类或间接子类。或者说 Java 中的每一个类都是 Object 的后代,Object 是所有类的祖先。一个类在定义时如果不通过 extends 指定其直接父类,系统会自动为该类继承 Object 类。
重写 Object 类的方法
- 每一个类都可以直接继承 Object 类的废自由方法,实例化对象可以直接调用这些方法。但是通常情况不会直接调用这些方法,而是需要对他们重写,因为父类中统一的方法并不能适用于所有子类。
- Object 类经常被子类所重写的方法有三个。
方法 | 描述 |
---|---|
public String toString() | 以字符常的形式返回该类的实例化对象信息 |
public boolean equals() | 判断两个对象是否相等 |
public native int hashCode() | 返回对象的散列码 |
toString() 方法
- 原生的 toString() 方法会返回对象的类名以及散列值
class People{
private int id;
private String name;
private int age;
private String gender;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
public class TestToString {
public static void main(String[] args) {
People people = new People();
people.setId(33);
people.setName("xiaoma");
people.setAge(20);
people.setGender("男");
System.out.println(people);
}
}
运行结果:
但是在实际开发中返回这样的信息意义不大,我们更希望看到的是对象的属性值,而非它的内存地址,所以我们需要对 toString 方法进行重写
class People{
..........
@Override
public String toString() {
return "People [id="+id+", name="+name+", age="+age+", gender="+gender+"]";
}
}
equals() 方法
- equals() 方法通过内存地址对两个对象进行判断,即两个对象的引用必须指向同一块内存程序才会认为他们相等。
- 但是在不同的场景下,这种方式不见得都适用。eg:String str1 = new Stirng(“hello”) , String str2 = new String(“hello”)。虽然 str1 和 str2 是两个完全不同的对象,但是他们的值相等,就可以认为这两个字符常相等。
- 在 String 类中已经对 equals 方法进行了重写,只要值相等即可,我们可以直接使用。
- 自定义类也可以根据需求对 equals 方法进行重写,如我们定义一个 People 类,创建该类的实例化对象,认为只要成员变量的值都相等就是同一个人
class People2{
private int id;
private String name;
private int age;
private String gender;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "People [id="+id+", name="+name+", age="+age+", gender="+gender+"]";
}
//---------------------------------------------------------------------------------------------------
@Override
public boolean equals(Object obj) {
People2 people = (People2) obj;
if(people.getId() == this.id && people.getName().equals(this.name) &&
people.getAge() == this.age && people.getGender().equals(this.gender)) {
return true;
}
return false;
}
//-----------------------------------------------------------------------------------------------------
}
public class TestEquals {
public static void main(String[] args) {
People2 people1 = new People2();
People2 people2 = new People2();
people1.setId(5);
people1.setName("张三");
people1.setAge(23);
people1.setGender("男");
people2.setId(5);
people2.setName("张三");
people2.setAge(23);
people2.setGender("男");
System.out.println(people1.equals(people2));
}
}
hashCode() 方法
- hashCode() 方法返回一个对象的散列值,这个值是由对象的内存地址结合对象内部信息得出的,任何两个对象的内存地址肯定是不一样的,但是在上面的例子中,我们认为如果两个 People 对象的成员变量值都相等,就是同一个对象,那么他们的散列值也应该相等,如果直接调用父类的 hashCode() 方法,两个对象的散列值是不相等的。
public class TestHashCode {
public static void main(String[] args) {
People2 people1 = new People2();
People2 people2 = new People2();
people1.setId(5);
people1.setName("张三");
people1.setAge(23);
people1.setGender("男");
people2.setId(5);
people2.setName("张三");
people2.setAge(23);
people2.setGender("男");
System.out.println(people1.hashCode());
System.out.println(people2.hashCode());
}
}
运行结果:
- 现在对 People 的 hashCode() 方法进行重写,将 id*name*age*gender 的值作为结果返回,name 和 gender 是字符串类型,值相等散列值就相等
class People{
............
@Override
public int hashCode() {
return this.id*this.name.hashCode()*this.age*this.gender.hashCode();
}
}
再次运行:
如此一来,成员变量值都相等的两个 People 对象,散列值也是相等的