Object超级父类

12/4/2022 Java

Object类是Java中所有类的父类,除了例如数值、字符和布尔类型的值,所有类都隐式继承Object类

# toString()方法

官方解释:a string representation of the object

  • 打印输出对象时默认输出object.toString(),如果不重写该方法,默认输出该对象的地址。
        Person person = new Person("小明","1",12);
        System.out.println(person);
        System.out.println(person.toString());
        System.out.println(person.getClass().getName()+"@" + Integer.toHexString(person.hashCode()));
com.yuwei.Person@1b6d3586
com.yuwei.Person@1b6d3586
com.yuwei.Person@1b6d3586
  • 地址值对于我们毫无意义,建议每个类都去重写toString()方法
@Override
public String toString() {
    return "Person{" +
            "name='" + name + '\'' +
            ", sex='" + sex + '\'' +
            ", age=" + age +
            '}';
}
  • 有些类重写了toString()方法,有些没有
  int[] it = {1,2,3,4};
        System.out.println(it);
        List list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        System.out.println(list);
[I@4554617c
[1, 2, 3]

通过输出结果我们可以看出,数组没有重写toString()方法,list列表重写了toString()方法。

# equals()方法

官方解释:if this object is the same as the obj argument;

用于检测一个对象是否等于另外一个对象,判断两个对象是否具有相同的引用。

public boolean equals(Object obj) {
        return (this == obj);
    }

# 默认地址比较

如果没有重写equals方法,那么Object类中默认进行==运算符的对象地址比较,只要不是一个对象,结果必然为false

注:==运算符都是比较对象的引用地址,而不是对象的值

Object o1 = new Object();
Object o2 = new Object();
Object o3 = o1;
System.out.println(o1.equals(o2));
System.out.println(o1.equals(o3));
System.out.println(o2.equals(o3));


System.out.println(o1==o2);
System.out.println(o1==o3);
System.out.println(o2==o3);
false
true
false
false
true
false

# 重写equals()方法、及hashCode()方法

对于多数类,Object父类的equals方法没有任何意义,经常需要检测的是两个业务对象是否相同。

(equals)==默认比较的是每个对象的散列(地址),所以如果重新定义equals方法,就必须重新定义hashCode方法

package com.yuwei.superobject;

import java.util.Objects;

public class Leader {

    private String name;

    private String address;

    private String idCard;

    public Leader(String name, String address, String idCard) {
        this.name = name;
        this.address = address;
        this.idCard = idCard;
    }

    public Leader() {
    }

    @Override
    public String toString() {
        return "Leader{" +
                "name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", idCard='" + idCard + '\'' +
                '}';
    }

    @Override
    public int hashCode() {
        //如果默认为名字、地址、身份证号码一致的对象为同一个对象,那么就需要把这三个值进行散列值处理。如果是比较一个,那么散列一个即可
        return Objects.hash(name, address, idCard);
    }
    
    @Override
    public boolean equals(Object o) {
        //先比较是不是同一个对象
        if (this == o) return true;
        //判空后比较是不是同一个类型的
        if (o == null || getClass() != o.getClass()) return false;
        Leader leader = (Leader) o;
        //比较这三个值是否相同
        return Objects.equals(name, leader.name) && Objects.equals(address, leader.address) && Objects.equals(idCard, leader.idCard);
    }

    
}

# 老生常谈

为什么String类型的数据不能使用==,而必须要使用equals方法,看例子。

  String a = new String("String");
        String b = "String";
        String c = "Str"+"ing";
        System.out.println(a==b);
        System.out.println(a==c);
        System.out.println(c==b);
false
false
true

很显然,如果使用==比较内存地址而不是实际值会出现这样的大问题

总结:其实如果我们理不清什么时候用哪个比较,只需要知道一点,那就是基本类型用==,对象用equals

# 补充

int[] a1 = {1,2,6,4};
int[] b1 = {1,2,3,4};
System.out.println(Arrays.equals(a1, b1));

Arrays.equals方法可以快捷的比较两个数组是否相同。

# getClass()方法

返回包含对象信息的类对象

# clone()方法

具体可参考该篇文章,主要用于深拷贝

Java深拷贝与浅拷贝 | 月牙弯弯 (opens new window)

更新时间: 12/4/2022, 5:51:12 PM
А зори здесь тихие-тихие
Lube