Object类有哪些自带方法?
#### registerNatives()
首先Object类有一个本地方法registerNatives(),会在类加载时调用,主要是将Object类中的一些本地方法绑定到指定的函数中去,便于之后调用。例如将hashCode和clone本地方法绑定到JVM_IHashCode和JVM_IHashCode函数。
```java
private static native void registerNatives();
static {
registerNatives();
}
```
想深入了解的朋友可以看看这两篇文章:
[Java之Thread源码registerNatives()深入理解](https://juejin.cn/post/6844903985111908359)
[Object类中的registerNatives方法的作用深入介绍](https://blog.csdn.net/Saintyyu/article/details/90452826)
#### getClass()
getClass()方法会返回对象的运行时类。
具体可以看下面这个例子:
有一个类Son,继承于Father类,instance的编译类型是Father,实际赋值的是一个Son对象,所以调用instance.getClass()获取的是instance对象的运行时类型,打印的类名是"com.test.Son"。
```java
package com.test;
class Father {}
class Son extends Father {}
Father instance = new Son();
Class class1 = instance.getClass();
System.out.println("class1 is"class1);
```
输出结果:
```java
class1 is class com.test.Son
```
#### Classs.forName()
与getClass()类似的方法还有两个,一个是Class类中的forName()方法,也是在运行时,根据传入的类名去加载类,然后返回与类关联的Class对象。也正是因为是动态加载,在编译时可以没有这个类,也不会对类名进行检验,所以有可能抛出ClassNotFoundException异常。
```java
public static Class<?> forName(String className)
throws ClassNotFoundException {
Class<?> caller = Reflection.getCallerClass();
return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}
```
可以自己尝试运行一下这段代码:
```java
Class class2 = null;
try {
class2 = Class.forName("com.test.Son");//如果实际不存在com.test.Son这个类,那么会抛出ClassNotFoundException异常
System.out.println(class2);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
```
```java
class2 is class com.test.Son
```
#### 类名+.class
还有一种方式是使用类名+.class来获取类关联的Class对象,与上面两种方法不同之处在于,它返回的是编译时类型,也就是在编译时,类加载器将类加载到JVM中,然后初始化一个Class对象返回。
```java
Class class3 = Son.class;
System.out.println(class3);
```
输出结果:
```java
class3 is class com.test.Son
```
PS:无论是使用哪种方式来获取类关联的Class对象,类都是只会加载一次,如果获取Class对象时,不会重复加载类。
#### clone()方法
clone()方法会创建并返回当前对象的副本。副本与原对象的区别在于它们相等,但是存储在不同的内存位置中。
```java
protected native Object clone() throws CloneNotSupportedException;
```
#### toString()方法
返回类名+@+hashCode的16进制字符串
#### wait()方法和notify()方法
```java
//timeout是超时时间,也就是等待的最大毫秒数,如果为0,代表会一直等待下去
public final native void wait(long timeout) throws InterruptedException;
public final native void notify();
public final native void notifyAll();
```
wait()
wait()方法可以让当前线程放弃对象的监视器(可以简单认为监视器就是一个锁),进入等待队列,进行等待,直到其他线程调用notify()或者notifyAll()后(或者过了超时时间),线程才会从等待队列,移动到同步队列,再次获得对象的监视器后才能继续执行。
notify()
notify()可以唤醒等待队列中的某一个线程,线程被唤醒后会从等待队列移动到同步队列,线程再次获得对象的监视器后才能继续执行。(然后调用notify()方法的线程会继续执行,在同步块中执行完毕后,会释放对象的监视器。)
notifyAll()
notifyAll()方法与notify()方法类似,只是会将等待队列中的所有线程唤醒。
可以看看这张图。

#### finalize
```java
//默认为空的实现,子类可以重写这个方法
protected void finalize() throws Throwable { }
```
当垃圾回收器确认某个对象不被任何其他对象引用时(即对象处于可恢复状态),系统在回收对象时,会调用finalize()方法,可以在这个方法中清理资源,在这个方法中,也有可能让对象重新获得引用,从而变成可达状态。
公众号进入网站体验更佳

