Java source code-Class Object (java.lang)

image.png

The Object class is the base class of all classes in Java, and all classes inherit Object by default.

1、registerNatives()

//本地方法,用c(c++)实现在dll文件内,通过JNI调用
private static native void registerNatives();
//对象初始化时调用此方法
static {
    registerNatives();
}
复制代码

2、getClass()

//本地方法,返回该类的Class对象
public final native Class<?> getClass();
复制代码

3、hashCode()

//本地方法,返回对象的哈希码值
public native int hashCode();
复制代码

4、equals(Object obj)

//比较两对象是否相等
public boolean equals(Object obj) {
    return (this == obj);
}
复制代码
  • The equals() method is implemented as "==" in the Object class, and "==" is used to compare whether the addresses of two objects are equal, that is, only when the two objects are the same object will return true. There are usually two types of classes that use this method:

    • If a subclass does not override this method, when comparing two objects for equality through equals(), it actually compares whether the two objects are the same object;
    • If a subclass overrides this method, for example, the String class overrides the equals() method to compare whether the contents of two classes are equal, then the contents of the two classes are compared, and the contents are equal (even if they are not the same class). ) returns true.
  • The function of the hash code is to determine the index position of the object in the hash table. The hashCode() method in the Object class is a local method, written in c (c++). By default, the memory address of the object on the heap is usually converted into an integer and then returned , so if the hashCode() method is not overridden, the hashes of the two objects will not be equal (addresses are different). The general contract between hashCode() and equals() is:

    • During the execution of a Java program, the same object must return the same value when hashCode() is called multiple times;
    • When equals() judges that two objects are equal, the return values ​​of hashCode() of the two objects must also be equal;
    • When equals() judges that two objects are not equal, the return values ​​of hashCode() of the two objects are not necessarily equal.

    Therefore, when comparing two objects, you can first compare whether the hashCode is equal. If they are not equal, the two objects are not equal; if the hashCode is equal, then call equals() to compare. This can greatly reduce the number of equals and improve the execution speed.

Based on the general agreement between hashCode() and equals() above, when you override the equals() method, you must also override the hashCode() method .

5、clone()

//创建并返回此对象的副本
//protected修饰:如果一个类未显示地重写该方法,其他类就不能直接调用该类实例的clone()方法
protected native Object clone() throws CloneNotSupportedException;
复制代码

The clone() method specifies:

  • 克隆的对象必须要实现 Cloneable 接口并重写 clone 方法,否则会报 CloneNotSupportedException 异常;

  • clone() 方法并不是 Cloneable 接口的方法,而是 Object 的一个 protected 方法。Cloneable 接口只是规定,如果一个类没有实现 Cloneable 接口又调用了 clone() 方法,就会抛出CloneNotSupportedException;

  • 该方法会创建类的新实例,并将其所有字段初始化为原对象相应字段的内容(字段通过赋值,字段本身不被克隆)-- 浅拷贝


补充:来看一下Cloneable接口(java.lang)源码

image.png

查看源码发现Cloneable接口中什么都没有定义,因此接口Cloneable只是一个标识,标识实现这个接口的类能够被克隆。(注意,并不是类实现了Cloneable接口才具有被克隆的性质,clone()是每个类都具有的方法而不是Cloneable接口的方法,只不过在clone()方法里要求被克隆的对象必须实现Cloneable接口并重写了clone()方法,否则会报CloneNotSupportedException异常)


6、toString()

//返回对象的字符串表示形式
public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
复制代码

7、notify()、notifyAll()

//唤醒在阻塞队列正在等待本对象的某个线程,被唤醒的线程进入就绪队列
public final native void notify();
复制代码
//唤醒在阻塞队列正在等待本对象的所有线程,被唤醒的线程进入就绪队列
public final native void notifyAll();
复制代码

只有持有该对象监视器的线程才能执行该方法,如果当前线程不是此对象的监视器持有者,报异常IllegalMonitorStateException

8、wait()

//使当前线程等待,放弃此对象监视器,进入阻塞队列,等到其他持有此对象监视器的线程执行notity()或notifyAll(),或指定的timeout(毫秒)已到,该线程才会被唤醒,进入就绪队列
public final native void wait(long timeout) throws InterruptedException;

复制代码
//timeout=0,表示只能等其他线程行notity()或notifyAll(),才能被唤醒
public final void wait() throws InterruptedException {
    wait(0);
}
复制代码
//比wait(long timeout)更精细的时间   1000000*timeout+nanos
public final void wait(long timeout, int nanos) throws InterruptedException {
    if (timeout < 0) {
        throw new IllegalArgumentException("timeout value is negative");
    }
​
    if (nanos < 0 || nanos > 999999) {
        throw new IllegalArgumentException(
                            "nanosecond timeout value out of range");
    }
​
    if (nanos > 0) {
        timeout++;
    }
​
    wait(timeout);
}
复制代码

notify()、notifyAll()和wait()在同步方法或同步代码块中成对使用

9、finalize()

protected void finalize() throws Throwable { }
复制代码
  • 当垃圾收集器通过可达性分析确定不再有对该对象的引用时,会对它进行第一次标记,随后进行一次筛选,筛选条件是这个对象是否覆盖了finalize()方法或者finalize()方法是否已经被虚拟机调用过,如果是,对象会被第二次标记并被回收。
  • If not, then the object will be put into the F-Queue queue, and later by a low-schedule low-priority (not necessarily immediately executed) Finalizer thread automatically created by the virtual machine to execute their finalize() method , and then the garbage collector will mark the object in the F-Queue queue for the second time. If the object in finalize() re-establishes an association with the reference chain, the object will not be marked for the second time, thus escaping The fate of being recycled by the garbage collector. But when the object faces the next recycling, it will not trigger finalize() and be recycled directly, because finalize() can only be executed once.
  • The finalize() method is expensive to run, has large uncertainty, and cannot guarantee the calling order of each object. It has now been officially declared deprecated. If you want to do some cleanup like "closing external resources", you can use try-finally instead of finalize(). (You can completely forget the finalize() method)

Guess you like

Origin juejin.im/post/7077875382300442661