Object类

目录

概念

获取对象信息  toString方法

对象比较equals方法

hashCode方法


概念

Object是java默认提供的一个类。Java中除了Object类,所有类都是存在继承关系的。默认会继承Object父类。即所有类的对象都可以使用Object的引用进行接收。Object类是所有类的父类,哪怕你没有显示去继承这个类。

举个例子:

class Person {}
class Student {}
class Women extends Person{}

public class Test10_3 {
    public static void func1(Object object) {
        System.out.println("object");
    }
    public static void main(String[] args) {
        func1(new Student());
        func1(new Women());
        func1(new Person());
    }
}

我们可以简单看一下Object中有哪些方法:

本篇博客我们主要来熟悉toString()方法、equals()方法、hashcode()方法

获取对象信息  toString方法

我们新建一个类Person

class Person {
    public String name;
    public int age;
    public Person(String name,int age) {
        this.age = age;
        this.name = name;
    }
}

在main方法中实例化一个Person对象,并输出

    public static void main(String[] args) {
        Person person = new Person("张三",10);
        System.out.println(person);
    }

 我们知道输出的是一个地址:

 

 这个地址是怎么来的呢,我们来看一下代码

在代码执行时,输出会调用println方法,我们来看看println方法的代码

println又会调用valueof这个方法,那么我们再来看valueof方法的代码

而valueof中又有一个toString方法,我们来看看他的代码

getClass().getName()就是获取当前路径(全路径),再加上一个@符号,再加上一个类似地址的东西并调用toHexString方法,将这个地址以16进制输出。

如果我们直接把toString方法写到我们的代码上,程序就不会调用默认的toString方法,而是会执行我们自己写的toString方法。

现在我们在Person类中  右键-->Generate-->toString-->全选-->确定 ,生成toString方法

class Person {
    public String name;
    public int age;
    public Person(String name,int age) {
        this.age = age;
        this.name = name;
    }
    //toString方法
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

此时再运行程序,输出的就不是一个地址了

 如果我们把toString方法里的代码修改以下,输出结果也会跟着改变。

    //toString方法
    @Override
    public String toString() {
        return "ok";
    }

那么为什么程序会执行我们写的toString方法呢。我们知道,println方法会调用valueof方法,valueof方法才会调用toString方法输出结果,我们再来看一下valueof的代码

 Object是所有类的父类,这里发生了动态绑定,本来调用的是父类的toString方法,可我们子类重写了toString方法,因此会执行子类重写的toString方法。

对象比较equals方法

我们先把刚刚生成的toString方法屏蔽,在main方法中实例化两个对象person1和person2,分别用“==”和equals比较person1和person2

    public static void main(String[] args) {
        Person person1 = new Person("张三",10);
        System.out.println(person1);
        Person person2 = new Person("张三",10);
        System.out.println(person2);
        System.out.println("============================");
        System.out.println(person1 == person2);
        System.out.println(person1.equals(person2));
    }

我们知道“==”比较的是person1和person2的值,那equals比较的到底是什么呢?我们来看一下equals的代码

this是谁:谁调用当前方法,谁就是this,这里person1就是this。 我们传入的参数是person2,所以此时equals比较的就是person1 == person2。和上面toString原理相同,如果我们重写equals方法,那么就会执行我们写的equals方法了。

    @Override
    public boolean equals(Object obj) {
        return true;
    }

如果我们这样重写equals方法,那么输出结果永远都是true

实际上我们可以按照我们需要的逻辑来重写equals方法,这里展示一个例子

    @Override
    public boolean equals(Object obj) {
        //如果传入的对象为空  返回false
        if (obj == null) {
            return false;
        }
        //如果两个引用指向同一个对象  返回true
        if (this == obj) {
            return true;
        }
        //如果传入对象不是Person类实例  返回false
        if (!(obj instanceof Person)) {
            return false;
        }
        //如果是Person类实例
        //将传入对象强转成Person类
        Person person = (Person) obj;
        //如果名字和年龄都相同  返回true 因为name是String型所以用equals比较
        return this.name.equals(person.name) && this.age== person.age;
    }

此时运行输出结果就是:

当然你也可以让编译器自动帮你生成:右键Generate-->equals() and hashcode()-->一路next-->完成。

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age && Objects.equals(name, person.name);
    }
    //马上讲到
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

如果以后是自定义的类型,那么一定记住重写equals方法。

hashCode方法

回忆一下,我们刚刚在讲解toString方法时遇到了hashCode()方法,他帮我们计算了一个具体的对象位置,这里涉及数据结构,我们暂时不讲解,只是说他是一个内存地址。

hashCode()方法是一个native方法,底层是用C/C++代码写的。我们看不到。

如果我们没有重写hashCode()方法的话,直接用person1和person2调用hashCode()方法会输出什么结果呢?

    public static void main(String[] args) {
        Person person1 = new Person("张三",10);
        System.out.println(person1.hashCode());
        Person person2 = new Person("张三",10);
        System.out.println(person2.hashCode());
    }

输出结果:

逻辑上,我们现在认为,如果两个对象的姓名年龄都一样的话,在内存中存放时只存一份即可。现在我们用生成的重写的hashCode()方法在运行一次代码

现在我们发现输出结果一样了。后期学到哈希表的时候就知道,两个一样的对象我们想要放在同一个位置,此时就可以利用重写hashCode()方法来做。

  • 12
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值