Object类

Object类是Java中所有类的父类,所有的类都是继承自Object或其子类。即使自己编写的类没有继承任何类,也会在编译的时候默认添加继承Object类。

package java.lang;

import jdk.internal.vm.annotation.IntrinsicCandidate;

public class Object {

    @IntrinsicCandidate
    public Object() {}

    @IntrinsicCandidate
    public final native Class<?> getClass();

    @IntrinsicCandidate
    public native int hashCode();

    public boolean equals(Object obj) {
        return (this == obj);
    }
    
    @IntrinsicCandidate
    protected native Object clone() throws CloneNotSupportedException;
    
    public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

    @IntrinsicCandidate
    public final native void notify();

    @IntrinsicCandidate
    public final native void notifyAll();

    public final void wait() throws InterruptedException {
        wait(0L);
    }

    public final native void wait(long timeoutMillis) throws InterruptedException;

    public final void wait(long timeoutMillis, int nanos) throws InterruptedException {
        if (timeoutMillis < 0) {
            throw new IllegalArgumentException("timeoutMillis value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }

        if (nanos > 0 && timeoutMillis < Long.MAX_VALUE) {
            timeoutMillis++;
        }

        wait(timeoutMillis);
    }
    
    @Deprecated(since="9")
    protected void finalize() throws Throwable { }
}

Object类既然是都有类的父类,那么所有类都能够使用Object类中的方法,同样的Object类的设计也是提取所有类都可能使用的方法。我们来分析一下这些方法:

public final native Class<?> getClass();

这个方法主要是用于获取类对象,在反射的时候很常用,这是一个native方法。

public native int hashCode();

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

这两个方法是用于判断对象是否是同一个对象设计的。hashCode值用于标识一个特定对象,equals默认判断两个对象的地址是否相同。如果要根据对象的某些属性相同就判定是同一个对象就可以重写equals方法和hashCode方法。

protected native Object clone() throws CloneNotSupportedException;

clone方法用于复制一个对象

@IntrinsicCandidate
public final native void notify();

@IntrinsicCandidate
public final native void notifyAll();

public final void wait() throws InterruptedException {
    wait(0L);
}

public final native void wait(long timeoutMillis) throws InterruptedException;

public final void wait(long timeoutMillis, int nanos) throws InterruptedException {
    if (timeoutMillis < 0) {
        throw new IllegalArgumentException("timeoutMillis value is negative");
    }

    if (nanos < 0 || nanos > 999999) {
        throw new IllegalArgumentException(
                            "nanosecond timeout value out of range");
    }

    if (nanos > 0 && timeoutMillis < Long.MAX_VALUE) {
        timeoutMillis++;
    }

    wait(timeoutMillis);
}

wait和notify方法与并发有关。

@Deprecated(since="9")
protected void finalize() throws Throwable { }

这是一个废弃的方法,作用是对象被回收的时候会回调这个方法。

浅拷贝和深拷贝

对象克隆就会遇到浅拷贝和深拷贝问题。

  • 浅拷贝:只复制对象本身,对象中的引用还是指向原来的对象
  • 深拷贝:复制对象及对象中的引用指向的对象都被复制

java object底层原理 java object..._java object底层原理

  • clone重写需要实现Clonable接口,否则会报异常

java object底层原理 java object..._java object底层原理_02



  • 并不是Clonable中也有一个clone方法,Clonable只是一个标记型的接口,其中没有任何方法,但是需要实现Clonable接口才能够重写Object中的clone方法,标志着这个类的对象可以复制。
    接下来是一个验证浅拷贝和深拷贝的demo
class Main {
    public static void main(String[] args) throws CloneNotSupportedException {
        Cat cat = new Cat();
        Dog dog = new Dog();
        Animal animal = new Animal(cat,dog);
        Animal animal1 = (Animal) animal.clone();
        System.out.println(cat);
        System.out.println(dog);
        System.out.println(animal1.cat);
        System.out.println(animal1.dog);
    }
}

class Animal implements Cloneable {
    public Cat cat;
    public Dog dog;

    public Animal() {
    }

    public Animal(Cat cat, Dog dog) {
        this.cat = cat;
        this.dog = dog;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
//        Animal result = new Animal();
//        result.cat = (Cat) this.cat.clone();
//        result.dog = (Dog) this.dog.clone();
//        return result;
        return super.clone();
    }
}

class Cat implements Cloneable {
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

class Dog implements Cloneable {
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

这里Animal类中包含两个对象,一个是Cat对象,一个是Dog对象。如果代码是现在这样,是属于浅拷贝,可以看到Animal类只是调用了父类Object类的clone方法,相当于只是复制了Animal对象自己,他所包含的cat和dog还是指向的原来的对象,打印如下:

Cat@3b07d329
Dog@41629346
Cat@3b07d329
Dog@41629346

animal和animal1中的cat和dog指向的是同一个对象。
如果将Animal中clone方法中的注释代码进行替换,则打印结果为:

Cat@3b07d329
Dog@41629346
Cat@404b9385
Dog@6d311334

这样Animal中所包含的对象也被拷贝了,是深拷贝。
还有一种深拷贝的方式是将对象序列化后再反序列化创建对象。