Object类学习

Object为所有类层次的超类,包括数组

Object类方法解析:

public class Object {

    /**
     * 构造方法 Constructs a new object.
     */
    @HotSpotIntrinsicCandidate
    public Object() {}
    /**
     * 返回this的运行时class
     * 实际返回的类型是调用getClass后(Class<? extends |X|>)静态类型擦除(|X|)的结果
     */
    public final native Class<?> getClass();

    /**
     * 默认返回对象的内存地址
     * 对象的equals相等必须返回相同的hashCode
     * 在一个程序中如果用于比较equals的信息没有改变,那么返回的hashCode也应该是不变的
     */
    public native int hashCode();

    /**
     * 指示某个其他对象是否“等于”此对象
     * Object方法默认实现时对比hashCode是否相等(即内存中是否为同一对象)
     * 重写equals方法一般必须重写hashCode方法,“相等”的对象必须拥有相同的hashCode
     * equals方法在non-null对象引用上实现了等价关系
     *  1.自反:x.equals(x) == ture
     *  2.对称:只有当x.equasl(y) == true 时, y.equals(x) 才应该返回true
     *  3.传递: x.equas(y) == true 并且 y.equals(z) == true ,则 x.equasl(z)也应该 返回true
     *  4.一致: 在未修改比较所用信息时,多次调用x.equals(y)应该返回相同的结果
     *  5.非空: x.equals(null) 应该返回false
     */
    public boolean equals(Object obj) {
        return (this == obj);
    }
    /**
     * 创建并返回此对象的副本
     * “复制”的精确含义取决于对象的类别,一般对于对于对象X有:
     *  1.x.clone()!=x
     *  2.x.clone().getClass() == x.getClass()
     *  3.x.clone().equals(x) == true
     *  4.x.clone() 一般会调用 super.clone() 来获得
     * 独立性:一般x'=x.clone(), x'与x无关 。所以可能需要修改 super.clone()返回对象的一个或多个字段(使用副本引用代替“深层结构”的可变对象引用)
     * 如果类没有实现Cloneable,将抛出CloneNotSupportedException,所有的数组(T[])都实现了CloneAble接口,并且返回类型是T[] (T是任何引用类型或基本类型)
     * 如果此方法创建的x'新实例使用x响应的字段内容初始化其所有字段为“浅拷贝”非“深拷贝”
     */
  protected native Object clone() throws CloneNotSupportedException;
  
    /**
     * 返回对象的字符串表示形式,应该 简洁但信息丰富 便于阅读 建议所有子类覆盖
     * 默认实现:类名称+@+哈希吗十六进制
     */

  public String toString() {
   return getClass().getName() + "@" + Integer.toHexString(hashCode());
  }
  
    /**
     * 唤醒正在等待该对象监视器的单个线程
     * 如果线程正在等待此对象,则随机唤醒其中一个,线程通常调用wait()方法之一等待对象的监视器
     * 被唤醒的线程将以通常的方式主动竞争此对象的监视器
     * 此方法只能由此对象的监视器拥有者线程调用,获取监视器的三种方式:
     *  1.执行该对象的 synchronized 实例方法
     *  2.执行该对象的synchronized 代码块
     *  3.Class类型的对象通过执行该类的synchronized静态方法
     * 一次只能又一个对象用于对象的监视器
   * IllegalMonitorStateException 非法监视器状态异常如果线程没有拥有监视器调用此方法 */
  public final native void notify();

    /**
     * 唤醒等待此对象监视器的所有线程
     * 线程通过调用wait()方法之一等待此对象的监视器
     * 被唤醒的线程将以通常的方式主动竞争此对象的监视器
     * 参考 notify()方法
     */
  public final native void notifyAll();

    /**
     * 造成当前线程等待 直到另外一个线程调用:notify()、notifyAll()或者超过指定时间
   * 当前线程必须拥有此对象的监视器 * 导致当前线程:T 处于对象的等待集中,然后放弃所有的同步声明(放弃持有的监视器)线程被禁止调度 处于休眠状态,以下四种方法将改变休眠状态: * 1.其他线程调用此对象的notify()方法,且此对象正好被唤醒 * 2.其他线程调用此对象的notigyAll()方法 * 3.其他线程中断(Thread.interrup())了 T * 4.指定的等待时间已经结束,如果指定的等待时间为0则不考虑超时,只是待唤醒 * 然后从该对象的等待集中删除此线程:T,并且重新启用线程调度,以通常的方式进行竞争
   * 一旦T获取了对象的对象的控制权对象上的所有同步声明都将恢复现状(即:调用wait()方法时的情况),然后T从wait()方法返回,因此返回时此对象和T的同步状态与调用wait()方法时相同 * 一次只能又一个对象用于对象的监视器
   * 线程可以在没有notified、interrupted、timing out 的情况被“虚假唤醒”,应该防范并继续等待
   * 如果当前线程被其他线程中断(Thread.interrupt())则抛出InterruptedException 并清除中断状态,恢复锁状态之前不会抛出此异常(什么情况)
   * 建议在while中检查等待条件,防止虚假唤醒可能导致的问题

   * IllegalMonitorStateException 非法监视器状态异常如果线程没有拥有监视器调用此方法 */
public final void wait(long timeoutMillis, int nanos) throws InterruptedException {
if (timeoutMillis < 0) {
throw new IllegalArgumentException("timeoutMillis value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException( "nanosecond timeout value out of range");
}
if (nanos > 0) {
timeoutMillis++;
}
wait(timeoutMillis);
}
 
    /**
     * 造成当前线程等待 直到另外一个线程调用:notify()、notifyAll()、Thread.interrupt()或者超过指定时间
   * 参考wait(long,int) * 导致当前线程:T 处于对象的等待集中,然后放弃所有的同步声明(放弃持有的监视器)线程被禁止调度 处于休眠状态,以下四种方法将改变休眠状态: *
   * IllegalMonitorStateException 非法监视器状态异常如果线程没有拥有监视器调用此方法 */
   public final native void wait(long timeoutMillis) throws InterruptedException;
    /**
     * 造成当前线程等待 直到notified、interrupted
   * 参考wait(long,int) * 导致当前线程:T 处于对象的等待集中,然后放弃所有的同步声明(放弃持有的监视器)线程被禁止调度 处于休眠状态,以下四种方法将改变休眠状态: *
   * IllegalMonitorStateException 非法监视器状态异常如果线程没有拥有监视器调用此方法 */
   public final void wait() throws InterruptedException {
    wait(0L);
   }


    /**
     * 当垃圾收集器确认此对象没有更多引用时,由垃圾收集器调用 。子类重写finalize()方法可以处理系统资源或其他清理
   * 通常的约定是当VM确认没有任何方法可以通过未死亡的线程访问到此对象时 * finalize()方法可以采取任何行动,包括使自己再次被其他对象可访问,但是通常的目的是在对象被不可撤销的销毁前执行清理操作如:I/O断开连接等 * Object.finalize()方法没有任何特殊处理,子类可以重写 * java不保证哪个线程将调用任何对象的finalize()方法,但是保证调用finalize()方法的线程不会持有任何用户可见的锁 * 一个对象的finalize()方法被调用后,不会被再次调用 * jvm永远不会调用用一个对象的finalize()方法多次 * 异常将导致对象的销毁被终止,但异常会被忽略

   * 类对于嵌入的non-heap资源有许多清除操作,确保实例的声明周期比资源要长 java.ref.Reference.reachablityFence 确保可以资源正在使用时,仍可访问
   * 子类应该避免覆盖finalise()方法除非在销毁前必须清理non-heap资源 * 和constructors不同finalize不会自动链式调用,所以需要显示调用supper.finalise,并且为了防止过早终结finalize链应该在try-finally块中确保始终调用

   * 终结机制存在本质上的问题,可能导致:性能问题、死锁、和挂起
   * 终结器中的错误可能导致资源泄露,并且无法取消
   * 不同对象的finalise方法没有指定排序,且无法保证最终确定的时间
   * 建议:还有non-heap资源的类应该提供方法以显示释放资源,并且如果有可能应该实现:AutoCloseable。Cleaner、PhantomReference提供了更有效的方法释放无法访问对象的资源 */
   protected void finalize() throws Throwable { }
 
posted @ 2019-07-07 18:26  gsanye  阅读(218)  评论(0编辑  收藏  举报