package java.lang;
/**
* Object类是Java中所有类的基类,所有类都直接或者间接的继承自该类
*/
public class Object {
/**
* native是修饰本地方法的关键词,方法对应的不是当前文件,本地方法的具体是在C(C++)的DLL中实现的,
* 然后通过JNI(Java Native Interface)调用
*/
/**
* 注册本地方法的函数
*/
private static native void registerNatives();
/**
* 静态代码块,在Object类在加载的时候,调用注册本地方法的函数,将本地方法注册到jvm
*/
static {
registerNatives();
}
/**
* 该方法返回的是该对象在运行时类的Class对象,对于每个被加载的类型,jvm都会为它创建一个java.lang.Class类的实例,
* 在方法区中存储此类的类型信息和一个指向类实例的引用,该引用把这个实例和存储在方法区中的类型数据关联起来。
* 因此get到的Class对象内包含的就是此类的类型信息。
* @return
*/
public final native Class<?> getClass();
/**
* 返回该对象的哈希值。使用本地方法是为了提高哈希表的性能。
* 但只有对象存储在HashSet,HashMap,HsahTable等以hash表为工作机制的容器的时候,才需要关心这个函数。
* hashcode常规规范规定hashcode必须满足:
* 1、在应用程序执行期间,对于同一对象,不进行修改的前提下,两次调用该方法得到的哈希值必须相同;
* 2、对于执行 equals()方法返回为 true的两个对象,执行 hashCode()方法,需返回相同的结果
* 3、对于执行 equals()方法返回为false的两个对象,执行 hashCode()方法,返回结果也可以相同,但不同可以提升哈希的性能。
* 若出现不同对象的哈希值相等,就称为hash冲突。
* 现在hashMap解决hash冲突使用了链表法(hashMap.get)。其他的还有开放地址法,再哈希法及公共溢出区法等等。
* @return
*/
public native int hashCode();
/**
* 用于判断两个对象的地址值是否相同
* 当此方法被重写时,通常有必要重写hashCode方法,
* 以维护hashCode方法的常规协定,即相等对象必须具有相等的哈希码。
* 但重写的equals(Object obj)方法必须具有以下特点:
* 1. reflexive(自反性),x.equals(x)的结果一定为 true
* 2. symmetric(对称性),x.equals(y)为 true,当且仅当 y.equals(x)为 true
* 3. transitive(传递性),当 x.equals(y)为true,y.equals(z)为true,可以推出:x.equals(z)
* 4. consistent(一致性),对于 x.equals(y),在不修改 x,y的前提下,调用几次的结果是不变的
* 5. 当x.equals(null) ,返回 false
* @return true代表对象与传入参数相等
*/
public boolean equals(Object obj) {
return (this == obj);
}
/**
* 该方法用于对象的拷贝,每个对象的堆上都存储有一个指向方法区中其类型信息的指针,而JVM通过这个指针来判断一个对象的类型,
* 由于只是简单的将对象的空间进行复制,所以它们具有相同的类型,即obj.clone().getClass()==obj.getClass()。
* 另外,若类具有引用类型的实例变量的话,也只是对这个引用进行拷贝,并不复制其引用的对象。
* 所以拷贝对象的引用与原对象的指向相同的对象,即为“浅拷贝”。
* 其实从内存方面来说简单一句话,就是看有没有开辟新的内存空间用于存储拷贝的对象,
* 浅拷贝只是拷贝一份引用,而深拷贝重新开辟堆内存存储拷贝的数据。
*
* 拷贝就是设计模式中原型模式的一种体现,原型模式是内存二进制流的拷贝,
* 要比new一个对象的性能好的多的多,特别是在for循环中产生大量对象时,原型模式能更好的体现其优点。
* 该方法是protected,因而所有实现了Cloneable接口的java类可来调用该方法。
*/
protected native Object clone() throws CloneNotSupportedException;
/**
* 返回一个由类名和此对象哈希值的无符号十六进制表示组成
* @return
*/
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
/**
* 唤醒在此对象同步模块上等待的单个或所有线程。
*/
public final native void notify();
public final native void notifyAll();
/**
* 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待,
* 在等待中的线程直到超时或者调用此对象的 notify()或 notifyAll() 方法才能唤醒。
* 当前线程必须拥有此对象的对象锁,即wait()方法必须写在同步模块(synchronized)中。
* @param timeout
* @throws InterruptedException
*/
public final native void wait(long timeout) throws InterruptedException;
/**
* 参数:
* timeout - 要等待的最长时间(以毫秒为单位)。
* nanos - 额外时间(以毫微秒为单位,范围是 0-999999)
*
* 抛出:
* IllegalArgumentException - 如果超时值是负数,或者毫微秒值不在 0-999999 范围内。
* IllegalMonitorStateException - 如果当前线程不是此对象监视器的所有者。
* InterruptedException - 如果在当前线程等待通知之前或者正在等待通知时,任何线程中断了当前线程。
* 在抛出此异常时,当前线程的 中断状态 被清除。
*/
public final void wait(long timeout, int nanos) throws InterruptedException {
// 判断传入的毫秒数是否合法,必须大于0
if (timeout < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
// 判断传入的纳秒数是否合法,1毫秒(ms)=1000000纳秒(ns)
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException("nanosecond timeout value out of range");
}
// 当传入的纳秒数合法时,将等待的毫秒数 +1
// 也就是等待时间无法控制在纳秒级别?
if (nanos > 0) {
timeout++;
}
//调用 wait(long timeout)函数,等待时间为原传入最大等待毫秒数 +1
wait(timeout);
}
// 本地方法,使当前线程等待,直到被 notify()或 notifyAll()方法唤醒
public final void wait() throws InterruptedException {
wait(0);
}
//本地方法,当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法
protected void finalize() throws Throwable { }
}