Java-Object类

Object类是所有类的爷爷类。

在开发中,如果一个操作可能接收所有类的对象,那么使用Object作为参数最合适。同时对于任意的一个简单Java类而言,理论上应该覆写Object类中的三个方法。

  1. 取得对象信息:public String toString();(Object默认toString输出一个字符串,该字符串由类名(对象是该类的一个实例)、at 标记符“@”和此对象哈希码的无符号十六进制表示组成。)
  2. 对象比较:public boolean equals(Object obj);
  3. 取得哈希码:public int hashCode();

一、hashCode()方法

hash值:Java中的hashCode方法就是根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,这个数值称作为散列值。

情景:当向集合中插入对象时,如何判别在集合中是否已经存在该对象了?(注意:集合中不允许重复的元素存在)。

  1. 使用equals():逐个进行比较,如果集合中已经存在一万条数据或者更多的数据,如果采用equals方法去逐一比较,效率很低。
  2. 使用hashCode():当集合要添加新的对象时,先调用这个对象的hashCode方法,得到对应的hashcode值。实际上在HashMap的具体实现中会用一个table保存已经存进去的对象的hashcode值,如果table中没有该hashcode值,它就可以直接存进去,不用再进行任何比较了;如果存在该hashcode值, 就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址。

重写hashCode()方法的基本规则:

  1. 当同一个对象多次调用hashCode() 方法应该返回相同的值。
  2. 当两个对象通过equals() 方法比较返回true时,则两个对象的hashCode()方法返回相等的值。
  3. 对象用作equals()方法比较标准的Field,都应该用来计算hashCode值。

二、clone()方法 — 深拷贝、浅拷贝

创建一个已有对象的副本。克隆使用须知:

  1. Object类中的clone()方法是一个自带的方法,效率远高于非Java自带方法。(clone方法首先会判对象是否实现了Cloneable接口,若无则抛出CloneNotSupportedException, 最后会调用internalClone。由于intervalClone是一个native方法,一般来说native方法的执行效率高于非native方法。)
  2. Object类中的clone()方法被protected修饰符修饰,因此如果要使用clone(),则必须继承Object类。
  3. Object.clone()返回一个Object对象,所以必须进行强制类型转换才可以得到我们所需的类型。

克隆的步骤:

  1. 创建一个对象。
  2. 将原有对象的数据导入新创建的数据中。
package com.joeaaa.demo08;

import java.util.Objects;

class Person{
    private String name;
    private int age;

    public Person() {
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @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);
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return (Person)super.clone();
    }
}

public class ObjectCloneTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person p0 = new Person("alex", 20);

        Person p1 = p0;
        System.out.println(p0 == p1);  // true

        Person p2 = (Person) p0.clone();
        System.out.println(p0 == p2); // fasle
    }
}
  1. p0 = p1只是引用而已,他们都指向了一个相同的对象Person(“alex”, 20) 。 可以把这种现象叫做引用的复制。
  2. 使用clone(),两个对象的地址是不同的,也就是说创建了新的对象, 而不是把原对象的地址赋给了一个新的引用变量。