[java][源码]java.lang.Object

1、基准jdk版本

jdk版本 JDK1.8

2、方法列表

java.lang.Object

序号 方法名 描述
1 Object 默认构造器
2 registerNatives 注册本地库
3 getClass 获取对象的运行时类
4 hashCode 获取对象的哈希码值
5 equals 比较是否相等
6 clone 复制对象
7 toString 返回对象的字符串表示形式
8 notify 唤醒等待此对象监视器的单个线程
9 notifyAll 唤醒此对象监视器上等待的所有线程
10 wait(long timeout) 使当前线程等待
11 wait(long timeout, int nanos) 使当前线程等待
12 wait 使当前线程等待
13 finalize 释放系统资源或执行其他清理

3、方法详细描述

3.1 Object

  构造器函数。一个类必须要有一个构造器的存在,如果没有显示声明,那么系统会默认创造一个无参构造器。

3.2 registerNatives

  该方法使用native来修饰,用native声明的方法表示告知JVM使用JNI技术调用C代码。该方法使用了静态代码块,就是一个类在初始化过程中必定会执行的内容,所以在类加载的时候是会执行该方法的,通过该方法来注册本地方法。

3.3 getClass

  该方法的作用是返回一个对象的运行时类,通过这个类对象我们可以获取该运行时类的相关属性和方法。

3.4 hashCode

  获取对象的哈希码值。 这个方法是为了支持散列表,例如: {@link java.util.HashMap}。

  • 当Java应用程序执行期间对同一对象多次调用{@code hashCode}方法时,只要对象的{@code equals}比较中使用的信息没有被修改,则该方法必须返回相同的整数。
  • 同一应用程序的多次启动执行,此整数不必保持一致。
  • 如果调用{@code equals(Object)}方法,两个对象相等,那么这两个对象中的每个对象调用{@code hashCode}方法必须产生相同的整数。
  • 调用{@link java.lang.Object#equals(java.lang.Object)}方法,如果两个对象不相等,则这两个对象中的每个对象调用{@code hashCode}方法必须产生不同的整数结果。但程序员知道不相等的对象生成不同的整数可能会提高哈希表的性能。
  • hashCode方法确实为不同的对象返回不同的整数,通常是通过将对象的内部地址转换为整数来实现的,但是Java编程语言不需要这种实现技术。

3.5 equals

  指示其他对象是否“等于”此对象。
  {@code equals}方法是为非空对象引用上实现等价关系:

  • 自反性:对于任何非空引用值{@code x}, {@code x.equals(x)}应该返回{@code true}。
  • 对称性:对于任何非空的引用值{@code x}和{@code y},{@code x.equals(y)}和{@code y.equals(x)}都返回{@code true}。
  • 传递性:对于任何非空的引用值{@code x}、{@code y}和{@code z},如果{@code x.equals(y)}返回{@code true},{@code y.equals(z)}返回{@code true},则{@code x.equals(z)}应返回{@code true}。
  • 一致性:如果对象在比较中信息没有被修改,那么对于任何非空的引用值{@code x}和{@code y},多次调用{@code x.equals(y)},返回一致的{@code true}或返回一致的{@code false}。
  • 对于任何非空引用值{@code x},{@code x.equals(null)}应返回{@code false}。

  注意,当重写此方法时,需要重写{@code hashCode}方法,以便维护{@code hashCode}方法的一般约定,该约定声明相等的对象必须具有相等的hash code。

3.6 clone

  创建并返回此对象的副本。“复制”的确切含义依赖于对象的类型。
一般来说,对于任何对象{@code x},表达式x.clone() != x返回{@code true},则x.clone().getClass() == x.getClass()将为{@code true},但这些不是绝对的要求。
按照约定,返回的对象应该通过调用{@code super.clone}获得。如果一个类及其所有超类(除了{@code Object})都遵守此约定,那么{@code x.clone().getClass() == x.getClass()}返回{@code true}。

  按照惯例,此方法返回的正在克隆的对象应独立于此对象。为了实现独立,在返回前,可能需要修改{@code super.clone}返回的对象的一个或多个字段;通常,用副本的引用替换被克隆对象的内部的任何可变对象的引用;如果一个类只包含原始类型或对不可变对象的引用,那么通常情况下{@code super.clone}返回的对象中不需要修改任何字段。

  注意:

  • 如果这个对象的类没有实现接口{@code Cloneable},那么会抛出{@code CloneNotSupportedException}。
  • 所有数组都实现了接口{@code Cloneable},所以数组类型调用{@code clone}方法返回{@code T[]},其中T是任何引用或原始类型。
  • 其他情况下,此方法将创建此对象的类的新实例,并使用此对象相应字段的内容初始化其所有字段,就像通过赋值一样,字段的内容本身并不是克隆的。因此,此方法执行此对象的“浅复制”,而不是“深复制”操作。
  • 类{@code Object}本身并不实现接口{@code Cloneable},因此对类为{@code Object}的对象调用{@code clone}方法将导致在运行时异常。

3.7 toString

  返回对象的字符串表示形式。
  通常,{@code toString}方法返回一个字符串,该字符串“以文本形式表示”该对象。结果应该是一个简洁但信息量大的表述,便于阅读。建议所有子类重写此方法。
  类{@code Object}的{@code toString}方法返回一个字符串,该字符串由对象是其实例的类的名称、at符号字符{@code@}和对象哈希代码的无符号十六进制表示组成。
  换句话说,此方法返回的字符串等于:

getClass().getName() + '@' + Integer.toHexString(hashCode())

3.8 notify

  唤醒等待此对象监视器的单个线程。
  如果有任何线程正在等待这个对象,则选择其中一个线程被唤醒。选择是任意的,由实现者自行决定。线程通过调用{@code wait}方法之一来等待对象的监视器。
  在当前线程放弃对该对象的锁定之前,唤醒的线程将无法继续。唤醒的线程将与任何其他线程竞争,这些线程可能正在积极竞争在此对象上同步;所以,唤醒的线程在成为下一个锁定此对象的线程时没有可靠的特权或劣势。
此方法只能由作为此对象监视器所有者的线程调用。线程通过以下三种方式之一成为对象监视器的所有者:

  • 通过执行该对象的同步实例方法。
  • 通过执行在对象上{@code synchronized}标识的同步语句主体。
  • 对于{@code Class,}类型的对象,执行该类的同步静态方法。

  一次只能有一个线程拥有对象的监视器。

3.9 notifyAll
  唤醒此对象监视器上等待的所有线程。
  线程通过调用{@code wait}方法之一来等待对象的监视器。在当前线程放弃对该对象的锁定之前,唤醒的线程将无法继续。唤醒的线程将与任何其他线程竞争,这些线程可能正在积极竞争在此对象上同步,所以,唤醒的线程在成为下一个锁定此对象的线程时没有可靠的特权或劣势。
  此方法只能由作为此对象监视器所有者的线程调用。请参阅{@code notify}方法,以了解线程成为监视器所有者的方式。

3.10 wait(long timeout)

  使当前线程等待,直到另一个线程调用此对象的{@link java.lang.Object#notify()}方法或{@link java.lang.Object#notifyAll()}方法,或者指定的时间已过。
  当前线程必须拥有此对象的监视器。
  此方法会导致当前线程(T)将自身放置在此对象的等待集合中,然后放弃对此对象的任何和所有同步声明。出于线程调度的目的,线程T将被禁用,并处于休眠状态,直到发生以下四种情况之一:

  • 其他一些线程为此对象调用{@code notify}方法,线程T碰巧被任意选择为要唤醒的线程;
  • 其他一些线程为此对象调用{@code notifyAll}方法;
  • 其他一些线程{@linkplain thread#interrupt()}中断线程T;
  • 指定的超时时间已经超时。但是,如果{@code timeout}为零,则不考虑超时,线程只需等待通知。

  然后从该对象的等待集合中删除线程T,并重新启用线程调度。然后,它与其他线程竞争对象上的同步权;一旦它获得了对象的控制权,它对对象的所有同步声明都将恢复到原来的状态,也就是说,恢复到调用{@code wait}方法时的状态,然后线程T从{@code wait}方法的调用返回。因此,从{@code wait}方法返回时,对象和线程{@code T}的同步状态与调用{@code wait}方法时完全相同。

  线程也可以在不被通知、中断或超时的情况下唤醒,即所谓的虚假唤醒。虽然这种情况在实践中很少发生,但应用程序必须通过测试本应导致线程被唤醒的条件,并在条件不满足时继续等待来防范这种情况。换句话说,等待应该总是以循环的形式出现,就像这样:

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

  (有关此主题的更多信息,请参阅Doug Lea的“Java并发编程(第二版)”(Addison-Wesley,2000)中的第3.2.3节,或Joshua Bloch的“有效Java编程语言指南”(Addison-Wesley,2001)中的第50项)。
  如果当前线程在等待之前或等待期间被任何线程{@linkplain java.lang.thread#interrupt()}中断,则抛出{@code InterruptedException}。在还原此对象的锁定状态之前,不会引发此异常。
  注意,{@code wait}方法在将当前线程放入此对象的等待集合中时,只解锁此对象;在线程等待期间,当前线程可能同步的任何其他对象都将保持锁定状态。
  此方法只能由作为此对象监视器所有者的线程调用。请参阅{@code notify}方法,以了解线程成为监视器所有者的方式。

3.11 wait(long timeout, int nanos)

  使当前线程等待,直到另一个线程调用此对象的{@link java.lang.Object#notify()}方法或{@link java.lang.Object#notifyAll()}方法,或者指定的时间已过。
  此方法类似于一个参数的{@code wait}方法,但它允许更好地控制在放弃之前等待通知的时间量。实时量(以纳秒为单位)由下式给出:1000000*timeout+nanos。
  在所有其他方面,此方法的作用与一个参数的方法{@link#wait(long)}相同。尤其是,{@code wait(0,0)}与{@code wait(0)}的意思相同。
当前线程必须拥有此对象的监视器。线程释放此监视器的所有权,并等待发生以下两种情况之一:

  • 另一个线程通过调用{@code notify}方法或{@code notifyAll}方法通知等待此对象监视器唤醒的线程。
  • 由{@code timeout}毫秒加上{@code nanos}纳秒参数指定的超时时间已过。
    然后线程等待,直到它可以重新获得监视器的所有权并继续执行。
    在一个参数的版本中,中断和虚假唤醒是可能的,这个方法应该在循环中使用:
synchronized (obj) {
              while (<condition does not hold>)
                  obj.wait(timeout, nanos);
             ... // Perform action appropriate to condition
         }

  此方法只能由作为此对象监视器所有者的线程调用。请参阅{@code notify}方法,以了解线程成为监视器所有者的方式。

3.12 wait

  使当前线程等待,直到另一个线程调用此对象的{@link java.lang.Object#notify()}方法或{@link java.lang.Object#notifyAll()}方法。换句话说,此方法的行为与执行调用{@code wait(0)}完全相同。
  当前线程必须拥有此对象的监视器。线程释放此监视器的所有权并等待,直到另一个线程通过调用{@code notify}方法或{@code notifyAll}方法通知等待此对象监视器唤醒的线程。然后线程等待,直到它可以重新获得监视器的所有权并继续执行。
  在一个参数的版本中,中断和虚假唤醒是可能的,这个方法应该在循环中使用:

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

  此方法只能由作为此对象监视器所有者的线程调用。请参阅{@code notify}方法,以了解线程成为监视器所有者的方式。

3.13 finalize

  当垃圾回收确定不再存在对对象的引用时,垃圾回收器对对象调用。子类重写{@code finalize}方法以释放系统资源或执行其他清理。
   如果是Java&trade,一般约定是调用{@code finalize};虚拟机已确定不再有任何方法可以让任何尚未终止的线程访问此对象,除非是由于某个其他对象或类的终结所采取的操作,该操作已准备好进行终结。{@code finalize}方法可以执行任何操作,包括使此对象对其他线程再次可用;但是,{@code finalize}的通常目的是在对象被不可撤销地丢弃之前执行清理操作。例如,表示输入/输出连接的对象的finalize方法可能会执行显式I/O事务,以便在永久丢弃该对象之前断开连接。
类{@code Object}的{@code finalize}方法不执行特殊操作;它只是正常返回。{@code Object}的子类可以重写此定义。
   Java编程语言不保证哪个线程将为任何给定对象调用{@code finalize}方法。但是,可以保证调用finalize的线程在调用finalize时不会持有任何用户可见的同步锁。如果finalize方法引发未捕获的异常,则将忽略该异常,并终止该对象的finalize。
   在为一个对象调用{@code finalize}方法之后,直到Java虚拟机再次确定不再有任何方法可以让任何尚未终止的线程访问该对象,包括其他已准备好完成的对象或类的可能操作,才采取进一步的操作,此时对象可能会被丢弃。
   对于任何给定的对象,{@code finalize}方法都不会被Java虚拟机多次调用。
   {@code finalize}方法引发的任何异常都会导致此对象的终止,否则将被忽略。

发布了9 篇原创文章 · 获赞 6 · 访问量 510

猜你喜欢

转载自blog.csdn.net/happygan520/article/details/104042039
今日推荐