java.lang.Object
类Object是类层次结构的根。 每个类都有Object作为超类。 所有对象,包括数组,实现这个类的方法。
类层次结构
构造方法
public Object(){}
方法
registerNatives
1 | private static native void registerNatives(); |
Java 中有两种方法:Java 方法和本地方法。Java 方法是由 Java 语言编写,编译成字节码,存储在 class 文件中。本地方法是由其他语言(比如 C 、C++ 、汇编)编写的,编译成和处理器相关的机器代码。本地方法保存在动态链接库中,格式是各个平台专有的。Java 方法是平台无关的,但本地方法不是。运行中的 Java 程序调用本地方法是,虚拟机装载包含这个本地方法的动态库。本地方法是联系 Java 程序和底层主机操作系统的连接方法。
本地方法的实现是由其他语言编写并保存在动态链接库中,因此在 Java 类中不需要方法实现。registerNatives() 本质上就是一个本地方法,但这又是一个区别于一般本地方法的本地方法,从本地方法名可以猜测出该方法是用来注册本地方法的。上述代码的功能就是先定义了registerNatives()方法,然后当该类被加载的时候,调用该方法完成对该类中本地方法的注册。
凡是包含registerNatives()本地方法的类,同时也包含了其他本地方法。所以,显然,当包含registerNatives()方法的类被加载的时候,注册的方法就是该类所包含的除了registerNatives()方法以外的所有本地方法。
一个Java程序要想调用一个本地方法,需要执行两个步骤:第一,通过System.loadLibrary()将包含本地方法实现的动态文件加载进内存;第二,当Java程序需要调用本地方法时,虚拟机在加载的动态文件中定位并链接该本地方法,从而得以执行本地方法。registerNatives()方法的作用就是取代第二步,让程序主动将本地方法链接到调用方,当Java程序需要调用本地方法时就可以直接调用,而不需要虚拟机再去定位并链接。
getClass
1 | public final native Class<?> getClass(); |
返回运行时类的Object 。 返回Class对象被 static synchronized 所表示的类方法修饰。
实际结果的类型是Class<? extends |X|>,其中|X| 是getClass被调用时静态类型的擦除。 例如,下列代码不需要强制转换。
1 | Number n = 0; |
hashcode
1 | public native int hashCode(); |
返回该对象的哈希码值。 为其他哈希表提供支持,例如 java.util.HashMap 。
一般 hashCode 满足以下规则:
在应用程序的执行期间,只要对象的equals方法的比较操作所用到的信息没有被修改,那么对同一个对象的多次调用,hashCode方法都必须始终返回同一个值。在一个应用程序与另一个应用程序的执行过程中,执行hashCode方法所返回的值可以不一致。
如果两个对象由 equals() 判断为 true ,那么他们的哈希码值必须相等。
如果两个对象由 equals() 判断为 false ,那么他们的哈希码值可以相等。应该为不同的对象生成不同的哈希码来提高哈希表的性能。哈希码值一般是将对象地址转成一个整数来得到。
equals
1 | public boolean equals(Object obj) { |
判断某个其他对象是否 “等于” 这个对象。默认比较的是两个对象的地址,当且仅当 this 和 obj 同时指向同一个对象时返回 true。
按照约定,equals要满足以下规则。
- 自反性: x.equals(x) 一定是true
- 对null: x.equals(null) 一定是false
- 对称性: x.equals(y) 和 y.equals(x)结果一致
- 传递性: a 和 b equals , b 和 c equals,那么 a 和 c也一定equals。
- 一致性: 在某个运行时期间,2个对象的状态的改变不会影响equals的决策结果,那么,在这个运行时期间,无论调用多少次equals,都返回相同的结果。
通常 equals 方法被重写时,必须重写 hashcode 方法。如果重写了 equals 方法,没有重写 hashcode 方法,判断两个值相等的对象时,当 equals 方法判断为 true(对象的值相等则为 true)时,由于两个值相等的对象地址不一样,所以生成的 hashcode 也不一样。违反了 hashcode 的规则:equals 为 true 两个对象的哈希码值必须相等。
clone
1 | protected native Object clone() throws CloneNotSupportedException; |
创建并返回此对象的副本。按照惯例,返回的对象应该通过调用super.clone
获得。
clone
的方法Object
执行特定的克隆操作。 首先,如果此对象的类不实现接口Cloneable
,则抛出CloneNotSupportedException
。 请注意,所有数组都被认为是实现接口Cloneable
,并且数组类型T[]
的clone
方法的返回类型是T[]
,其中T是任何引用或原始类型。 否则,该方法将创建该对象的类的新实例,并将其所有字段初始化为完全符合该对象的相应字段的内容,就像通过赋值一样。 这些字段的内容本身不被克隆。 因此,该方法执行该对象的“浅拷贝”,而不是“深度拷贝”操作。
Object
类本身并不实现接口Cloneable
,因此在类别为Object
的对象上调用clone
方法将导致运行时抛出异常
toString
1 | public String toString() { |
返回一个代表对象的字符串。这个字符串中含有对象的相关信息,便于阅读。建议所有的子类重写这个方法。
Object 类的 toString 方法返回对象的类名 + ‘@’ + 对象的哈希码值得十六进制数。
notify
1 | public final native void notify(); |
唤醒任意一个正在等待该对象的监视器锁(对象的内置锁)的线程。一个线程通过调用 wait 方法来等待对象的监视器锁。被唤醒的线程只有在当前线程放弃了对象的锁之后才能被执行。被唤醒的线程与其他线程平等竞争对象的锁。该方法只能由作为该对象的监视器的所有者线程调用。
线程有三种方式成为对象监视器锁的所有者:
通过执行对象的同步方法。
通过执行对象的同步语句(锁住此对象)。
执行类的同步静态方法。
notifyAll
1 | public final native void notifyAll(); |
唤醒所有一个正在等待该对象的监视器锁的线程。一个线程通过调用 wait 方法来等待对象的监视器锁。
wait
1 | public final native void wait(long timeout) throws InterruptedException; |
使当前线程阻塞直到另一个线程调用此对象的 notify 方法或 notifyAll 方法或指定的时间已过,当前线程变为就绪状态。当前线程必须拥有此对象的监视器锁。
1 | public final void wait(long timeout, int nanos) throws InterruptedException { |
与只有一个参数的 wait 方法类似,更加精细地控制等待被唤醒的时间直到放弃。
1 | public final void wait() throws InterruptedException { |
使当前线程阻塞直到另一个线程调用此对象的 notify 方法或 notifyAll 方法。
finalize
1 | protected void finalize() throws Throwable { } |
当垃圾收集器确定不再有该对象的引用时调用。finalize 方法通常的目的是在对象不可撤销丢弃之前执行清除动作。甚至finalize 方法可以让此对象再次可用于其他线程而避免被垃圾收集器清除。finalize 方法只能调用一次。
参考: