Object类是类层次结构的根,它是 Java其他所有类的超类。
在介绍 Object源码前,补充 native关键字:
native关键词修饰的方法是一个原生态方法(本地方法),方法对应的实现不是在当前文件,具体是用C(C++)在DLL中实现的,然后通过JNI调用
以下的源码是 jdk1.8 版本:
public class Object {
// 本地方法,作用为注册一些本地方法
private static native void registerNatives();
// 对象初始化时自动调用此方法
static {
registerNatives();
}
// 本地方法,返回当前的运行时类
public final native Class<?> getClass();
/**
* 本地方法,计算哈希值,相关的三个规定:
* 1. 在应用程序执行期间,对于同一对象,不进行修改的前提下,两次调用该方法得到的哈希值必须相同
* 2. 对于执行 equals()方法返回为 true的两个对象,执行 hashCode()方法,需返回相同的结果
* 3. 如果根据 equals()方法,两个对象不相等,执行 hashCode()方法,返回结果不必一定不同,但不同可以提升哈希的性能
* @return 该对象的哈希值
*/
public native int hashCode();
/**
* 用于判断两个对象的内容是否相等,具有以下特点:
* 1. reflexive(自反性),x.equals(x)的结果一定为 true
* 2. symmetric(对称性),x.equals(y)为 true,当且仅当 y.equals(x)为 true
* 3. transitive(传递性),当 x.equals(y),y.equals(z),可以推出:x.equals(z)
* 4. consistent(一致性),对于 x.equals(y),在不修改 x,y的前提下,调用几次的结果是不变的
* 5. 当参数为 null,返回 false
* 同时要注意,当这个方法被重写时, hashCode()也应该同步被重写
* @return true代表对象与传入参数相等
*/
public boolean equals(Object obj) {
return (this == obj);
}
/**
* 创建并返回该对象的副本,一般要求(非必要):
* 1. x.clone() != x返回 true
* 2. x.clone().getClass() == x.getClass()返回 true
* 3. x.clone().equals(x) true
*
* 注意,Object自身并没有实现 Cloneable接口,因此不能对其调用 clone方法
* @return 一个复制的实例
*/
protected native Object clone() throws CloneNotSupportedException;
// 返回该对象的字符串表示
// 获取字节码文件的对应全路径名例如java.lang.Object,并将哈希值转成16进制数格式的字符串输出
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
// 本地方法,唤醒在此对象监视器上等待的单个线程
public final native void notify();
// 本地方法,唤醒在此对象监视器上等待的所有线程
public final native void notifyAll();
/**
* 本地方法,使当前线程等待,直到被 notify()或 notifyAll()方法唤醒,或者过去了指定的时间
* @param 等待的最大毫秒数
*/
public final native void wait(long timeout) throws InterruptedException;
* 本地方法,使当前线程等待,直到被 notify()或 notifyAll()方法唤醒,或者过去了指定的时间
* @param timeout 等待的最大毫秒数
* @param nanos 额外的时间,以纳秒为范围 0-999999
*/
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");
}
// 当传入的纳秒数合法时,将毫秒数 +1
if (nanos > 0) {
timeout++;
}
// 调用 wait()函数,等待时间为原传入最大等待毫秒数 +1
wait(timeout);
}
// 本地方法,使当前线程等待,直到被 notify()或 notifyAll()方法唤醒
public final void wait() throws InterruptedException {
wait(0);
}
// 本地方法,当垃圾回收期确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法
protected void finalize() throws Throwable { }
}
对于上面的源代码,有一个地方我个人比较不解:
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);
}
关键在与纳秒数,而 1000,000 ns = 1 ms,相当于我们传入的纳秒数,范围从 [1ns, 1ms),但对于上面的代码,传入 100ns,跟 500ns,并没有什么不同,所以说明源码并不支持纳秒级别的休眠时间。
而对比 jdk1.6的源代码:
public final void wait(long timeout, int nanos) throws nterruptedException {
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 >= 500000 || (nanos != 0 && timeout == 0)) {
timeout++;
}
wait(timeout);
}
当超过半毫秒,或者当毫秒数为 0,纳秒数不为 0时,加 1。对于这种,800ns跟 900ns也没有不同,个人推荐纳秒级别过于低,因此对纳秒进行粗略的处理,但不太能理解从 jdk1.6到 jdk1.8对这个函数的改动有什么意义。欢迎有其他想法的博友在下方留言交流。
本文探讨了Java中Object类的重要地位,作为所有类的超类。文章重点关注了Object类中的native方法,特别是关于线程休眠的实现。通过对比jdk1.6和jdk1.8的源代码,作者指出在纳秒级别的休眠时间处理上存在差异,并讨论了这些差异可能的影响。作者邀请读者分享对这一变化的看法。

8961

被折叠的 条评论
为什么被折叠?



