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()方法类似,只是会将等待队列中的所有线程唤醒。 可以看看这张图。 ![image.png](https://images.codewd.com/d2e86d9674b976a13dba34735c9e3495.png) #### finalize ```java //默认为空的实现,子类可以重写这个方法 protected void finalize() throws Throwable { } ``` 当垃圾回收器确认某个对象不被任何其他对象引用时(即对象处于可恢复状态),系统在回收对象时,会调用finalize()方法,可以在这个方法中清理资源,在这个方法中,也有可能让对象重新获得引用,从而变成可达状态。