java.lang.object
说明:java.lang.Object类是java中所有类的父类,所有类默认继承Object。也就是java中任何类都会继承Object中的所有方法和属性(注:子类是可以继承父类的私有方法和属性,只是没有直接访问的权限)。下面具体看看Object中的方法
1.registerNatives()
private static native void registerNatives();
static {
registerNatives();
}
定义了一个本地方法,使用静态代码块,在加载该类的时候调用该本地方法。
问:什么是本地方法呢?
Java有两种方法:Java方法和本地方法。Java方法是由Java语言编写,编译成字节码,存储在class文件中。本地方法是由其他语言(比如C,C++,或者汇编)编写的,编译成和处理器相关的机器代码。本地方法保存在动态连接库中,格式是各个平台专有的。Java方法是平台无关的,不过本地方法却不是。运行中的Java程序调用本地方法时,虚拟机装载包含这个本地方法的动态库,并调用这个方法。本地方法是联系Java程序和底层主机操作系统的连接方法。
registerNatives作用是什么?
在Object类中,除了有registerNatives这个本地方法之外,还有hashCode()、clone()等本地方法,而在Class类中有forName0()这样的本地方法等等。也就是说,凡是包含registerNatives()本地方法的类,同时也包含了其他本地方法。所以,显然,当包含registerNatives()方法的类被加载的时候,就是为了注册除了registerNatives()方法以外的其他所有本地方法。
为什么要注册?
一个Java程序要想调用一个本地方法,需要执行两个步骤:
通过System.loadLibrary()将包含本地方法实现的动态文件加载进内存; 当Java程序需要调用本地方法时,虚拟机在加载的动态文件中定位并链接该本地方法,从而得以执行本地方法。 registerNatives()方法的作用就是取代第二步,让程序主动将本地方法链接到调用方,当Java程序需要调用本地方法时就可以直接调用,而不需要虚拟机再去定位并链接。
2.getClass()
public final native Class<?> getClass();
该方法被声明为public final native方法,这说明该方法无法被重写,且是一个本地方法。 该方法的作用是返回一个对象的运行时类,通过这个类对象我们可以获取该运行时类的相关属性和方法。 反射就是基于此基础实现的。
3.hashCode()
public native int hashCode();
该方法用 native 声明的本地方法,可以被重写,作用是返回对象的散列码,是 int 类型的数值。 该方法有3个约定:
- 在程序运行时期间,只要对象的变化不会影响equals方法的判断结果,那么,在这个期间无论调用多少次hashCode,都必须返回同一个散列码。
- 通过equals调用返回true的2个对象的hashCode一定一样。
- 通过equasl返回false的2个对象的散列码可以一样也可以不一样。 也就是我们经常说的: 也就是说:
- 两个对象相等,其hashCode一定相同。
- 两个对象不相等,其hashCode有可能相同。
- hashCode相同的两个对象,不一定相等。
- hashCode不相同的两个对象,一定不相等。
4.equals(Object obj)
public boolean equals(Object obj) {
return (this == obj);
}
this表示当前对象,该方法是比较传入对象和当前对象的引用是否一致。不能用来比较对象内容相等,所以一般需要重写equals方法。
5.clone()
protected native Object clone() throws CloneNotSupportedException;
该方法不能直接使用,clone()的正确调用是需要实现Cloneable接口,如果没有实现Cloneable接口,子类直接调用Object类的clone()方法,则会抛出CloneNotSupportedException异常。 来看一下Cloneable的源码:
public interface Cloneable {
}
Cloneable接口仅是一个表示接口,它本身不包含任何方法,只是用来指示Object.clone()可以合法的被子类所调用。
优点:
速度快,而且灵活。速度快是因为clone方法最终会调用Object.clone()方法,这是一个native方法,本质是内存块复制,所以在速度上比使用new创建对象要快。灵活是因为可以在运行时动态的获取对象的类型以及状态,从而创建一个对象。
缺点:
缺点也很明显:实现深拷贝较为困难,需要整个类继承的所有类以及所有的属性都很好的实现clone方法。另外就是需要处理CloneNotSupportedException异常。
6.toString()
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
从源码可以看出返回该对象运行时的类名加上hashCode()等。内容可读性并不好,所以通常都要重写toString,输出需要的实例信息,比如某些属性的值。
7.notify()
public final native void notify();
该方法用于唤醒某一个等待的线程。
8.notifyAll()
public final native void notifyAll();
该方法用于唤醒所有等待的线程。
9.wait(long timeout)
public final native void wait(long timeout) throws InterruptedException;
该方法用于唤醒所有等待的线程。
10.wait(long timeout)
public final native void wait(long timeout) throws InterruptedException;
该方法用于线程释放资源锁,进入线程等待。在timeout的时间后会被唤醒,进行资源争夺。
11.wait(long timeout, int 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);
}
该方法用于线程释放资源锁,进入线程等待。在timeout的时间后会被唤醒,此方法多一个微秒参数,如果微秒大于0,毫秒加1。
12.wait()
public final void wait() throws InterruptedException {
wait(0);
}
该方法用于线程释放资源锁,进入线程等待
13.finalize()
protected void finalize() throws Throwable { }
该方法用于垃圾回收,一般由 JVM 自动调用,一般不需要程序员去手动调用该方法。