Object

216 阅读3分钟

Object类是类层次结构的根,每个类都以Object类作为超类,每个对象(包括数组)都实现了Object类的方法。

下面代码是数组实现了Object类方法的例证。

String[] strArr = {"a", "b"};
strArr.hashCode();
strArr.clone();
strArr.equals(strArr);
strArr.toString();
strArr.getClass();

下面是Object类中方法的介绍(以JDK 8 介绍):

1. getClass()

  1. getClass()由类的实例调用,获取运行时实例的类的Class对象。
  2. .class由类名调用,获取类的Class对象。

2. equals()、hashCode()

2.1 equals()

==与equals()

  1. == 判断两个对象的地址是不是相等:如果是基本数据类型,比较的是值;如果是引用数据类型,比较的是内存地址。另外,Integer内部类IntegerCache会缓存[-128,h]的Integer对象(其中h默认为127,可由-XX:AutoBoxCacheMax=设置),在此范围内,==比较时会为同一对象。
    Integer integer1 = 100;
    Integer integer2 = 100;
    System.out.println(integer1 == integer2);  // true
    
    Integer integer3 = 300;
    Integer integer4 = 300;
    System.out.println(integer3 == integer4);  // false
    
    Integer integer5 = new Integer(100);
    Integer integer6 = new Integer(100);
    System.out.println(integer5 == integer6);  // false
    
  2. equals()判断两个对象是否相等:如果类没有覆写equals(),那么与==作用相同,比较两个对象的地址是不是相等;我们一般通过覆写equals()判断两个对象的内容是不是相等。
    public boolean equals(Object obj) {
        return (this == obj);
    }
    

2.3 hashCode()

hashCode()方法的作用:以Set为例,当新加一个对象时,需要判断现有集合中是否已经存在与此对象相等的对象,如果没有hashCode(),需要将Set进行一次遍历,并逐一用equals()判断两个对象是否相等,时间复杂度为O(n),通过hashCode(),可先计算出即将加入的对象的哈希码,根据哈希算法计算此对象的位置,直接判断此位置上是否已有对象。

  1. 如果两个对象的equals()判断相等,那么这两个对象调用hashCode()返回的哈希码也必须相等。
  2. 如果两个对象的hashCode()返回的哈希码相等,这两个对象的equals()不一定相等。
  3. 重写了equals()后,需要重写hashCode()。

3. clone()

clone()实现的是浅拷贝:基本数据类型进行值拷贝,引用数据类型进行引用传递般的拷贝。一个类对象浅拷贝时,需要实现Cloneable接口,调用clone()。

深拷贝:拷贝所有的属性,并拷贝属性指向的动态内存的分配。

实现深拷贝的方式:

  1. 重写clone(),对内部的引用类型变量,再进行一次拷贝。

    @AllArgsConstructor
    public class Person implements Cloneable {
        private String name;
        
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
    
    @AllArgsConstructor
    public class Animal implements Cloneable {
        private Person host;
        private String name;
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            Animal animal = (Animal) super.clone();
            animal.host = (Person) host.clone();
            return animal;
        }
    }
    
  2. 序列化方式实现深拷贝:先将要拷贝对象写入到内存中的字节流中,然后再从字节流中读出刚刚存储的信息,作为一个新对象返回,新对象和原对象不存在任何地址上的共享,自然实现了深拷贝。

    @AllArgsConstructor
    @Data
    public class Person implements Serializable {
        private String name;
    }
    
    @AllArgsConstructor
    @Data
    public class Animal implements Serializable {
        private Person host;
        private String name;
    }
    
    public class CloneUtil {
        public static <T extends Serializable> T clone(T obj) {
            T cloneObj = null;
            try {
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                ObjectOutputStream oos = null;
    
                oos = new ObjectOutputStream(bos);
    
                oos.writeObject(obj);
                oos.close();
    
                ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
                ObjectInputStream ois = new ObjectInputStream(bis);
                cloneObj = (T) ois.readObject();
                ois.close();
                return cloneObj;
            } catch (Exception e) {
                return null;
            }
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            Animal animal1 = new Animal(new Person("mustang"), "dog");
            Animal animal2 = CloneUtil.clone(animal1);
            System.out.println(animal1.getHost() == animal2.getHost());
        }
    }
    

4. toString()

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

5. wait()、notify()、notifyAll()

6. finalize()