zoukankan      html  css  js  c++  java
  • Object类

    Object类源码阅读:

      Object类中包含的方法:

      1.private static native void registerNatives();

    static {

        registerNatives();
    }
    说明:就是对几个本地方法进行注册

    2.public final native Class<?> getClass();
    说明:返回object运行时类。返回的是类对象。

    3.public native int hashCode()
    获取对象的哈希值。不可以根据hashcode值判断两个对象是否相等。因为不同的对象可能会生成相同的hashcode值。虽然不能根据hashcode值判断两个对象是否相等,
    但是可以直接根据hashcode值判断两个对象不等,如果两个对象的hashcode值不等,则必定是两个不同的对象。如果要判断两个对象是否真正相等,必须通过equals方法。
    如果要判断两个对象是否真正相等,必须通过equals方法。

      也就是说对于两个对象,如果调用equals方法得到的结果为true,则两个对象的hashcode值必定相等;

      如果equals方法得到的结果为false,则两个对象的hashcode值不一定不同;

      如果两个对象的hashcode值不等,则equals方法得到的结果必定为false

      如果两个对象的hashcode值相等,则equals方法得到的结果未知。

    重写equal方法,必须要重写hashCode方法。因为通过equal判断相等的两个对象,hashCode方法必须返回相同的hashCode值。

    4. public boolean equals(Object obj) {

        return (this == obj);
    }

    对于非空对象的引用,x.equals(x)应该返回true

    对于非空对象的引用,x.equals(y) 返回truey.equals(x)也应该返回true

    传递性,x.equals(y) 返回truey.equals(z)返回true, 则x.equals(z)也应该返回true

    对于非空对象,x.equals(null)应当返回false

    只有当xy是同一对象时, x==y才会返回true

    所以,当重写equals方法时,有必要重写hashCode方法,因为equals方法返回true的两个对象,其hash值必须相等。

    5.protected native Object clone() throws CloneNotSupportedException;

    一般来说,x.clone() != x返回truex.clone().getClass() == x.getClass()返回true,但是并非必须。

    x.clone().equals(x)并非绝对的必要条件。

    惯例,该方法返回的对象可以通过调用super.clone获得。如果一个类和他的父类遵守这个惯例,则x.clone().getClass() == x.getClass()

    按照惯例,通过该方法返回的对象和原对象应该是独立的。为了达到这个独立性,有必要在返回该对象前,修改一个或多个字段。这意味着,被复制对象的深层次结构也应该被复制,并替换引用。如果一个对象只包含基本数据类型,则其字段不需要被修改。

    如果一个类要实现clone方法。需要实现Cloneable接口,否则就会抛出CloneNotSupportedException。所有的数组都被认为实现了该接口。该接口只复制了字段,字段中的内容没有进行复制,所以该方法是浅复制,而不是深复制。

    Object对象本身没有实现Cloneable接口,所以调用Object里面的clone方法会抛出CloneNotSupportedException异常。

    1. public String toString() {
          return getClass().getName() + "@" + Integer.toHexString(hashCode());
      }

    返回对象的字符串表示形式。返回的结果要简洁扼要,便于阅读。推荐所有的子类重写该方法。Object对象的toString方法返回getClass().getName() + '@' + Integer.toHexString(hashCode()).

    1. public final native void notify();

    唤醒一个等待该对象监视器的线程。如果有多个线程在等待获取锁,其中一个线程将被唤醒。
    被唤醒线程的选择是随机的。被唤醒的线程无法继续执行,直到当前线程释放对象的锁。被唤醒线程将会和其他使用synchronize方法获取锁的线程进行竞争。被唤醒的锁享受并不可靠的优先级。
    一个线程成为线程监听器拥有者的方式有三种:
    1.对象的synchronized方法
    2.对象的synchronized代码段
    3.类对象的静态synchronized方法,获取类队形本身的锁

    1. public final native void notifyAll();

    唤醒所有等待该对象监听器的线程。被唤醒线程不能继续运行,直到当前线程释放对象的锁。被唤醒线程将和其他线程同等竞争获取对象的锁。被唤醒线程并不具有可靠的优先权去获取对象的锁。该方法只能被拥有对象监听器的线程使用。如果当前线程并未拥有该对象的监听器,调用该方法将会抛出IllegalMonitorStateException异常。

    1. public final native void wait(long timeout) throws InterruptedException;

    该方法导致当前线程等待,知道其他线程调用notify()或者notifyAll(), 或者经过特定的时间。当前线程必须拥有对象监视器。

    该方法会让当前线程把自己放到改对象对应等待队列中,然后放弃所有对该对象同步请求,
    线程将不会参与调度,并保持休眠状态,直到下面四种情况之一发生:
    1.其他线程调用该对象notify方法, 并且该线程被选中成为被唤醒的线程。
    2.其他线程调用该对象notifyAll方法
    3.其他线程interrupt该线程
    4.经过特定时间,如果timeout0,则需要等待,知道被通知。

    该线程被移出等待的集合,并且变成可以调度的线程。
    该线程将会与其他线程针对该对象的synchronize进行一般情况下的竞争。一旦该线程获得锁,该线程对该对象的同步申请都会恢复原状,即回到wait方法被调用时的状态。然后,线程将从wait方法中返回。在从wait方法返回过程中,该对象和线程的同步状态和wait方法被调用时的一致。

    除了唤醒,中断,超时以外,一个线程也可以被唤醒,这称为虚假唤醒。实际中很少发生这种情况。应用必须避免这种情况,可以通过测试该线程等待的条件,如果条件不满足,则继续等待。也就是说,等待应该放到循环中,就像下面这样:

    synchronized (obj) {
          while (<condition does not hold>)
              obj.wait(timeout);
          ... // Perform action appropriate to condition
    }

    如果该线程在等待中之前和等待中被其他线程中断,InterruptedException将会被抛出。在该对象的锁的状态被重置前,异常不会被抛出。

    注意,该对象的对应的等待队列中的线程,只能有该对象进行解锁。该线程等待过程中,如果该线程拥有的其他对象的同步,其他对象将保持锁定。该方法只能被该对象的监视器拥有者使用。

    1. 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);
      }

    该方法导致当前线程等待,直到另外一个线程调用notify()或者notifyAll()方法唤醒。或者其他线程中断该线程,或者经过了固定的时间。该方法和单参数方法类似。但是该方法允许精确控制放弃前等待通知的时间。实际等待的时间是以纳秒为单位的,按照下面的公式计算:

    1000000*timeout+nanos

    在其他所有的方面,该方法做的事情和单参数方法是一致的。特别的,wait(0,0)wait(0)是一致的。

    当前线程必须拥有该对象的监视器。线程释放监视器的拥有权和等待,知道下面两者之一发生:

    1. 另外一个线程通过notify或者notifyAll唤醒等待该对象监视器的线程。
    2. 超时时间,经过timeout秒和nanoseconds毫秒之和。

    线程继续等待,直到该线程能重新获得监视器的拥有权,然后继续执行。和单参数方法类似,中断和虚假唤醒是有可能的,所以该方法应该用在循环中:

    synchronized (obj) {

         while (<condition does not hold>)

             obj.wait(timeout, nanos);

             ... // Perform action appropriate to condition

    }

    该方法只能被拥有该对象监视器的拥有者调用。可以参见notify方法得知线程获得一个监视器拥有权的方法。

    11.  public final void wait() throws InterruptedException {

       wait(0);

    }

    该方法导致当前线程等待,直到其他线程调用该对象的notify()或者notifyAll方法。换句话说,该方法的执行效果和wait(0)是一致的。当前线程必须拥有对象的监视器。线程释放监视器的拥有权和等待直到其他线程,使用notify或者notifyAll方法唤醒等待该对象的监视器的线程。和单参数方法一致,中断和虚假唤醒是有可能的。因此,该方法应该总是被用在循环中:

    synchronized (obj) {

        while (<condition does not hold>)

            obj.wait();

            ... // Perform action appropriate to condition

     }

    该方法只能被该对象监视器的拥有者调用。可以参见notify方法得知线程获得一个监视器拥有权的方法。

    12.  protected void finalize() throws Throwable { }

    当垃圾回收确定该对象没有多余的引用时,垃圾回收器会调用该方法。{@code finalize}的一般约定是,当Java™时调用它;当其他线程没有办法进入该对象时,虚拟机会决定调用该方法。该方法调用一些方法,包括使对象对其他线程重新可见。该方法的一般目的是在对象不能撤销的丢弃前执行一些清理工作。例如,在对象呗持久化丢弃钱,该方法会断开该对象的一些连接,这些连接用于输入和输出。

    对象的finalize方法没有做什么特殊的操作,仅仅是正常返回。子类可能会重写该方法。对于给定的对象,java编程语言不能保证哪个线程会调用这个方法。但是调用该方法的线程必须拥有用户可见的同步锁。如果,该方法被捕获到异常,异常将会被忽略,析构也将终止。

    当一个对象的该方法被调用后,将不会有进一步的动作被执行,直到虚拟机发现其他线程没有任何方法进入该对象,这些方法包括将要被丢弃的其他对象或类对该对象采取了操作。

    该方法被虚拟机调用的次数不会超过一次。该方法抛出的任何异常都会导致对象析构的终止,但是这些异常会被忽略。

  • 相关阅读:
    趁热讲讲skin.xml支持的标签和attributes
    如何配置和编译ogre 1.7.0 + cegui 0.7.1
    关于OGRE基础教程6中CEGUI的layout文件can not locate的问题
    skin.xml皮肤配置讲解
    OCX控件注册相关(检查是否注册,注册,反注册)
    重回博客园继续我的 GUI库
    窗口类的定义
    UI库需要完成的任务
    屏幕截图代码
    深入C++的默认构造函数1
  • 原文地址:https://www.cnblogs.com/chwy/p/10652416.html
Copyright © 2011-2022 走看看