package my.java.lang;
/**
* 所有类的基类,所有的对象(包括数组)都继承Object类
*
* @author unascribed
* @version 1.73, 03/30/06
* @see java.lang.Class
* @since JDK1.0
*/
public class Object {
/**
* 初始化
*/
private static native void registerNatives();
static {
registerNatives();
}
/**
* 返回对象的(运行时)类对象,由该类的{@code static synchronized}方法加锁
*
* @return 返回值的编译类型实际为调用对象的声明类型的擦除,例如Number n = 0;则n.getClass()的编译类型为Class<? extends
* Number>,运行时类型为Class<Integer>
*
*/
@Override
public final native Class<?> getClass();
// 以下native方法可以重写,注释中主要说明重写这些方法的一些约定规范/////////////////
/**
* 返回hash值,默认实现是native的
*
* <pre>
* hashCode取值的常规约定如下:
*
* 同一java应用中,如果equals()用到的信息没有变更,同一对象的hashCode()始终返回相同的值
* 如果两个对象equals()返回true,则hashCode()返回相同数值
* 反之非equals的对象允许返回相同的hashCode
*
* 但Object.hashCode()保证不同对象一定返回不同hashCode(实现为将对象的内存地址转化为整数签名)
*
* @return a hash code value for this object.
* @see java.lang.Object#equals(java.lang.Object)
* @see java.util.Hashtable
*/
@Override
public native int hashCode();
/**
* 判断两个对象“相等”,一般需要遵守如下约定(不是强制,但是违反可能造成奇怪的错误):
*
* <pre>
* 自反性:x.equals(x)==true
* 对称性:x.equals(y)==y.equals(x)
* 传递性:x.equals(y)==true && y.equals(z)== x.equals(z)==true
* 一致性:如果equals()实现中用到的属性没有发生变化,重复调用x.equals(y)始终返回相同的结果
* x.equals(null)==false
* Object类的equals方法是最严格的相等判断,即通过==直接比较对象
*
* 一般来说,如果重写equals(),也需要同时重写hashCode(),以实现hashCode()的约定(equal的对象具有相同的hashCode)
*
* @see #hashCode()
* @see java.util.Hashtable
*/
public boolean equals(Object obj) {
return (this == obj);
}
/**
* 返回本对象的一个复制。返回值的具体情形依赖于调用对象的类型
*
* 一般约定是以下条件为true(但并非强制要求)
*
* <pre>
* x.clone() != x
* x.clone().getClass() == x.getClass()
* x.clone().equals(x)
*
* 根据约定,返回值对象应该通过super.clone()来创建
* 如果某类及其所有祖先(Object除外)都满足此约定,则x.clone().getClass() == x.getClass()自动满足
*
* 根据约定,clone()的返回值应与原对象独立(隔离)。为实现这点,有时需要修改<tt>super.clone</tt>返回值的一些属性
* 通常就是复制对象属性引用结构里的所有引用。如果所有属性都是原始类型,那么就不需要这步了
*
* Object.clone()实现略有特别:
* 首先,如果该类没有实现Cloneable接口,则方法会抛出<tt>CloneNotSupportedException</tt> (所有数组对象默认实现Cloneable)
* 否则,方法返回此类的一个新对象,其所有属性均与原对象保持一致
* 注意非原始类型属性本身并不进行复制,因此这是一个“浅克隆”实现
*
* <tt>Object</tt>类本身没有实现<tt>Cloneable</tt>,因此调用一个实际类型为Object的对象的clone()方法会报错
* (这地方有点绕,注意是实际类型,Cloneable调用super.clone()是可以的,即使super是Object)
*
* @return a clone of this instance.
* @exception CloneNotSupportedException if the object's class does not support the
* <code>Cloneable</code> interface. Subclasses that override the
* <code>clone</code> method can also throw this exception to indicate that an
* instance cannot be cloned.
* @see java.lang.Cloneable
*/
@Override
protected native Object clone() throws CloneNotSupportedException;
/**
* 默认的toString()写法,类名加hashCode(内存地址签名)
*/
@Override
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
// 以下native方法为线程相关的方法,虚拟机底层实现,一般不重写//////////////////////
/**
* (随机)唤醒一个在本对象上等待的线程
*
* <pre>
* 被唤醒的线程首先竞争wait时放弃的(本对象的)锁,持锁后才能继续运行
* 唤醒的线程在竞争锁的时候没有任何额外的优先权
*
* 此方法只能被本对象的所有者线程调用,所有者指满足以下条件之一(其实就是持有锁的线程):
* 1.正在执行该对象的synchronized实例方法
* 2.正在执行行该对象锁定的synchronized代码块
* 3.如果该对象是Class对象且正在执行对应类的synchronized静态方法
*
* 根据锁的特性,同一个对象同时只有一个线程作为所有者
*
* @exception IllegalMonitorStateException 非对象持有者线程调用抛出
* @see java.lang.Object#notifyAll()
* @see java.lang.Object#wait()
*/
@Override
public final native void notify();
/**
* 唤醒所有在本类等待的线程,其他特性与notify相同
*/
@Override
public final native void notifyAll();
/**
* 当前线程进入等待状态
*
* <pre>
* 本线程保持此状态直到竞态的其他线程调用notify()或notifyAll(),或者方法超时
* 当前线程必须持有此对象的锁(在synchronized(this)中),否则抛出IllegalMonitorStateException
* 所以调用方法的对象一般被用来当做锁
*
* 调用wait的线程放弃所有已持有该对象锁的synchronized代码并进入阻塞,知道以下条件之一满足:
* 1.其他线程调用该对象的notify(),而本线程恰好被(随机)选中为被唤醒的线程
* 2.其他线程调用该对象的notifyAll()。
* 3.其他线程调用Thread.interrupt()中断本线程
* 4.等待时间超过timeout(如果timeout不是0)
*
* 注意本线程退出等待状态,不意味着立刻继续执行,因为有可能需要重新竞争锁
* 线程退出等待(等价于wait方法返回)时,该线程的所有状态与调用wait时完全一致
*
* 线程还可能通过一种“虚假唤醒(spurious wakeup)”的方式来唤醒
* 此方式很少被有意使用,但必须注意防止其发生引起意外错误,应用在wait返回后应该显式校验线程唤醒的条件
* 也就是说wait应该总是以如下的方式在循环中使用
*
* <pre>
* synchronized (obj) {
* while (<condition does not hold>)
* obj.wait(timeout);
* ... // Perform action appropriate to condition
* }
* </pre>
*
* (For more information on this topic, see Section 3.2.3 in Doug Lea's
* "Concurrent Programming in Java (Second Edition)" (Addison-Wesley, 2000), or Item 50 in
* Joshua Bloch's "Effective Java Programming Language Guide" (Addison-Wesley, 2001).
*
* 如果本线程在等待期间被(其他线程)调用Thread.interrupt(),则会抛出<tt>InterruptedException</tt>
* 该异常会等到线程重新持锁后才会实际抛出(而不是Thread.interrupt()调用后立刻抛出
*
* 注意wait()方法只是交出本对象的锁持有,如果线程还持有其他锁,则(等待期间)其他锁也不会被放弃(注意死锁隐患)
*
* @param timeout 单位:毫秒
* @exception IllegalArgumentException if the value of timeout is negative.
* @exception IllegalMonitorStateException if the current thread is not the owner of the
* object's monitor.
* @exception InterruptedException if any thread interrupted the current thread before or while
* the current thread was waiting for a notification. The <i>interrupted
* status</i> of the current thread is cleared when this exception is thrown.
* @see java.lang.Object#notify()
* @see java.lang.Object#notifyAll()
*/
@Override
public final native void wait(long timeout) throws InterruptedException;
/**
* 重载,对超时时间做更精细的控制
*
* 实际超时时间为:1000000 * timeout + nanos(纳秒)
*/
@Override
public final void wait(long timeout, int nanos) throws InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException("timeout value is negative");
} else if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException("nanosecond timeout value out of range");
}
if (nanos >= 500000 || (nanos != 0 && timeout == 0)) {
timeout++;
}
wait(timeout);
}
/**
* 重载,不超时(永久等待notify/interrupt)
*/
@Override
public final void wait() throws InterruptedException {
wait(0);
}
// ////////////////////////
/**
* gc时如果该对象没有引用,垃圾回收器调用此方法做自定义的系统资源释放及其他清理工作
*
* <pre>
* finalize()方法约定只有在如下情况下被调用:
* jvm确认此对象不会被任何活跃线程访问到(其他对象/类的finalize方法除外)
*
* finalize()原则上允许做任何操作,包括使对象重新可用
* 但通常的目的是在对象不可逆转地被丢弃之前做清理工作,如代表I/O连接的对象断开连接
*
* Object.finalize()没有具体实现,具体内容由子类重写
*
* java不保证具体什么线程会调用finalize(),但是保证调用时线程不会持有任何用户可见的锁
* 如果finalize()抛出未捕获的异常,该异常会被直接忽略
*
* jvm不会调用同一对象的finalize()超过一次
*
* @throws Throwable the <code>Exception</code>
* raised by this method
*/
@Override
protected void finalize() throws Throwable {
}
}