深入研究java.lang.Object类
前言:Java的类库日益庞大。所包括的类和接口也不计其数。但当中有一些非常重要的类和接口,是Java类库中的核心部分。常见的有String、Object、Class、Collection、ClassLoader、System、Runtime...,掌握类是灵活Java这门语言的基础。而这些类一般都非常好理解和运用,须要做深入的研究和实践才干掌握。
一、概述:
Object类是全部Java类的祖先。每一个类都使用 Object 作为超类。
全部对象(包含数组)都实现这个类的方法。
在不明白给出超类的情况下。Java会自己主动把Object作为要定义类的超类。
能够使用类型为Object的变量指向随意类型的对象。
Object类有一个默认构造方法pubilc Object(),在构造子类实例时,都会先调用这个默认构造方法。
Object类的变量仅仅能用作各种值的通用持有者。要对他们进行不论什么专门的操作,都须要知道它们的原始类型并进行类型转换。
比如:
Object obj = new MyObject();
MyObject x = (MyObject)obj;
二、API预览
Object()
默认构造方法
clone()
创建并返回此对象的一个副本。
equals(Object obj)
指示某个其它对象是否与此对象“相等”。
finalize()
当垃圾回收器确定不存在对该对象的很多其它引用时,由对象的垃圾回收器调用此方法。
getClass()
返回一个对象的执行时类。
hashCode()
返回该对象的哈希码值。
notify()
唤醒在此对象监视器上等待的单个线程。
notifyAll()
唤醒在此对象监视器上等待的全部线程。
toString()
返回该对象的字符串表示。
wait()
导致当前的线程等待,直到其它线程调用此对象的 notify() 方法或 notifyAll() 方法。
wait(long timeout)
导致当前的线程等待,直到其它线程调用此对象的 notify() 方法或 notifyAll() 方法。或者超过指定的时间量。
wait(long timeout, int nanos)
导致当前的线程等待。直到其它线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其它某个线程中断当前线程,或者已超过某个实际时间量。
三、方法使用说明
1、equals()方法:用于測试某个对象是否同还有一个对象相等。它在Object类中的实现是推断两个对象是否指向同一块内存区域。
这中測试用处不大,由于即使内容同样的对象。内存区域也是不同的。假设想測试对象是否相等。就须要覆盖此方法。进行更有意义的比較。比如
class Employee{
... //此样例来自《java核心技术》卷一
public boolean equals(Object otherObj){
//高速測试是否是同一个对象
if(this == otherObj) return true;
//假设显式參数为null,必须返回false
if(otherObj == null) reutrn false;
//假设类不匹配。就不可能相等
if(getClass() != otherObj.getClass()) return false;
//如今已经知道otherObj是个非空的Employee对象
Employee other = (Employee)otherObj;
//測试全部的字段是否相等
return name.equals(other.name)
&& salary == other.salary
&& hireDay.equals(other.hireDay);
}
}
Java语言规范要求equals方法具有以下的特点:
自反性:对于不论什么非空引用值 x。x.equals(x) 都应返回 true。
对称性:对于不论什么非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。
传递性:对于不论什么非空引用值 x、y 和 z,假设 x.equals(y) 返回 true。而且 y.equals(z) 返回 true。那么 x.equals(z) 应返回 true。
一致性:对于不论什么非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比較中所用的信息没有被改动。
对于不论什么非空引用值 x,x.equals(null) 都应返回 false。
从这里看出,上面的样例是Java规范的equals方法的标准实现,推荐用上面样例的写法实现类的equals方法。
2、toString():返回该对象的字符串表示。Object类中的toString()方法会打印出类名和对象的内存位置。差点儿每一个类都会覆盖该方法,以便打印对该对象当前状态的表示。
大多数(非所有)toString()方法都遵循例如以下格式:类名[字段名=值,字段名=值...]。当然,子类应该定义自己的toString()方法。比如:
public String toString(){
reurn "Employee[name=" + name + ",salary=" + salary + ",hireDay=" + hireDay + "]";
}
toString()方法是非常重要的调试工具,非常多标准类库中的类都定义了toString()方法。以便程序猿获得实用的调试信息。
3、clone():创建并返回此对象的一个副本。“副本”的准确含义可能依赖于对象的类。
这样做的目的是。对于不论什么对象 x。
表达式: x.clone() != x为 true,表达式: x.clone().getClass() == x.getClass()也为 true,但这些并没必要要满足的要求。
普通情况下: x.clone().equals(x)为 true。但这并没必要要满足的要求。
4、notify():唤醒在此对象监视器上等待的单个线程。假设全部线程都在此对象上等待,则会选择唤醒当中一个线程。选择是随意性的,并在对实现做出决定时发生。
线程通过调用当中一个 wait 方法,在对象的监视器上等待。
直到当前线程放弃此对象上的锁定,才干继续运行被唤醒的线程。被唤醒的线程将以常规方式与在该对象上主动同步的其它全部线程进行竞争。比如,唤醒的线程在作为锁定此对象的下一个线程方面没有可靠的特权或劣势。
此方法仅仅应由作为此对象监视器的全部者的线程来调用。通过下面三种方法之中的一个,线程能够成为此对象监视器的全部者:
- 通过运行此对象的同步实例方法。
- 通过运行在此对象上进行同步的
synchronized语句的正文。 - 对于
Class类型的对象,能够通过运行该类的同步静态方法。
一次仅仅能有一个线程拥有对象的监视器。
5、notifyAll():唤醒在此对象监视器上等待的全部线程。线程通过调用当中一个
wait 方法,在对象的监视器上等待。
直到当前线程放弃此对象上的锁定。才干继续运行被唤醒的线程。
被唤醒的线程将以常规方式与在该对象上主动同步的其它全部线程进行竞争。比如,唤醒的线程在作为锁定此对象的下一个线程方面没有可靠的特权或劣势。
6、wait(long timeout):在其它线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量前。导致当前线程等待。
当前线程必须拥有此对象监视器。
此方法导致当前线程(称之为 T)将其自身放置在对象的等待集中,然后放弃此对象上的全部同步要求。
出于线程调度目的,在发生下面四种情况之中的一个前,线程 T 被禁用,且处于休眠状态:
- 其它某个线程调用此对象的 notify 方法。而且线程 T 碰巧被任选为被唤醒的线程。
- 其它某个线程调用此对象的 notifyAll 方法。
- 其它某个线程中断线程 T。
- 大约已经到达指定的实际时间。可是,假设 timeout 为零,则不考虑实际时间。在获得通知前该线程将一直等待。 然后。从对象的等待集中删除线程 T。并又一次进行线程调度。然后,该线程以常规方式与其它线程竞争,以获得在该对象上同步的权利。一旦获得对该对象的控制权,该对象上的全部其同步声明都将被恢复到曾经的状态,这就是调用 wait 方法时的情况。
然后,线程 T 从 wait 方法的调用中返回。所以。从 wait 方法返回时。该对象和线程 T 的同步状态与调用 wait 方法时的情况全然同样。
在没有被通知、中断或超时的情况下,线程还能够唤醒一个所谓的虚假唤醒 (spurious wakeup)。尽管这样的情况在实践中非常少发生,可是应用程序必须通过以下方式防止其发生,即相应该导致该线程被提醒的条件进行測试。假设不满足该条件,则继续等待。
换句话说。等待应总是发生在循环中,如以下的演示样例:
synchronized (obj) {
while (<condition does not hold>)
obj.wait(timeout);
... // Perform action appropriate to condition
}
7、wait(long timeout, int nanos):在其它线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其它某个线程中断当前线程,或者已超过某个实际时间量前。导致当前线程等待。
此方法类似于一个參数的 wait 方法,但它同意更好地控制在放弃之前等待通知的时间量。用毫微秒度量的实际时间量能够通过下面公式计算出来:
1000000*timeout+nanos在其它全部方面。此方法运行的操作与带有一个參数的 wait(long) 方法同样。须要特别指出的是,wait(0, 0) 与 wait(0) 同样。
当前线程必须拥有此对象监视器。该线程公布对此监视器的全部权,并等待以下两个条件之中的一个发生:
- 其它线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。
- timeout 毫秒值与 nanos 毫微秒參数值之和指定的超时时间已用完。
然后,该线程等到又一次获得对监视器的全部权后才干继续运行。
对于某一个參数的版本号,实现中断和虚假唤醒是有可能的,而且此方法应始终在循环中使用:
synchronized (obj) {
while (<condition does not hold>)
obj.wait(timeout, nanos);
... // Perform action appropriate to condition
}
8、wait():在其它线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。换句话说。此方法的行为就好像它仅运行 wait(0) 调用一样。
当前线程必须拥有此对象监视器。该线程公布对此监视器的全部权并等待,直到其它线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。
然后该线程将等到又一次获得对监视器的全部权后才干继续运行。
对于某一个參数的版本号。实现中断和虚假唤醒是可能的。并且此方法应始终在循环中使用:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
9、finalize():当垃圾回收器确定不存在对该对象的很多其它引用时,由对象的垃圾回收器调用此方法。
子类重写 finalize 方法。以配置系统资源或运行其它清除。
finalize 的常规协定是:当 JavaTM 虚拟机已确定尚未终止的不论什么线程无法再通过不论什么方法訪问此对象时,将调用此方法。除非因为准备终止的其它某个对象或类的终结操作运行了某个操作。
finalize 方法能够採取不论什么操作,当中包含再次使此对象对其它线程可用;只是。finalize 的主要目的是在不可撤消地丢弃对象之前运行清除操作。比如。表示输入/输出连接的对象的 finalize 方法可运行显式 I/O 事务。以便在永久丢弃对象之前中断连接。
Object 类的 finalize 方法运行非特殊性操作;它仅运行一些常规返回。
Object 的子类能够重写此定义。
Java 编程语言不保证哪个线程将调用某个给定对象的 finalize 方法。但能够保证在调用 finalize 时。调用 finalize 的线程将不会持有不论什么用户可见的同步锁定。假设 finalize 方法抛出未捕获的异常,那么该异常将被忽略。而且该对象的终结操作将终止。
在启用某个对象的 finalize 方法后,将不会运行进一步操作,直到 Java 虚拟机再次确定尚未终止的不论什么线程无法再通过不论什么方法訪问此对象,当中包含由准备终止的其它对象或类运行的可能操作,在运行该操作时。对象可能被丢弃。
对于不论什么给定对象,Java 虚拟机最多仅仅调用一次 finalize 方法。
finalize 方法抛出的不论什么异常都会导致此对象的终结操作停止,但能够通过其它方法忽略它。
深入研究java.lang.Object类的更多相关文章
- 深入研究java.lang.ThreadLocal类 (转)
深入研究java.lang.ThreadLocal类 一.概述 ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是thr ...
- 深入研究java.lang.ProcessBuilder类
深入研究java.lang.ProcessBuilder类 一.概述 ProcessBuilder类是J2SE 1.5在java.lang中新添加的一个新类,此类用于创建操作系统进程,它 ...
- 深入研究java.lang.Process类
一.概述 Process类是一个抽象类(所有的方法均是抽象的),封装了一个进程(即一个执行程序). Process 类提供了执行从进程输入.执行输出到进程.等待进程完成.检查进程的退出状态 ...
- java.lang.Object类与equals()及toString()的使用
1.Object类是所有Java类的根父类 2.如果在类的声明中未使用extends关键字指明其父类,则默认父类为java.lang.Object类 3.Object类中的功能(属性.方法)就具有通用 ...
- 深入研究java.lang.Runtime类【转】
转自:http://blog.csdn.net/lastsweetop/article/details/3961911 目录(?)[-] javalang 类 Runtime getRuntime e ...
- JDK1.8源码(一)——java.lang.Object类
本系列博客将对JDK1.8版本的相关类从源码层次进行介绍,JDK8的下载地址. 首先介绍JDK中所有类的基类——java.lang.Object. Object 类属于 java.lang 包,此包下 ...
- java.lang.Object类
Object类是java所有对象的基类,包含着java最核心和最基础的类,在编译时会自动导入.具体的类结构图: 1.构造器 public Object(); 大部分情况下,Java中通过形如 new ...
- java.lang.Object类(JDK1.7)
1.Object的类方法 package java.lang; public class Object { private static native void registerNatives(); ...
- 写出java.lang.Object类的六个常用方法
java是面向对象的语言,而Object类是java中所有类的顶级父类(根类). 每个类都使用Object类作为超类,所有对象(包括数组)都实现这个类的方法,即使一个类没有用extends明确指出继承 ...
随机推荐
- running Fluent on Apocrita Cluster
two files: code.sh, code.jou code.sh #!/bin/bash #$ -cwd #$ -j y #$ -m bea #$ -M k.ai@qmul.ac.uk #$ ...
- 【BZOJ 1588】[HNOI2002] 营业额统计(Treap)
Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每 ...
- POJ 1144 Network (求割点)
题意: 给定一幅无向图, 求出图的割点. 割点模板:http://www.cnblogs.com/Jadon97/p/8328750.html 分析: 输入有点麻烦, 用stringsteam 会比较 ...
- 大数据学习——linux系统的网卡配置步骤
ifconfig 查看ip,没有ip时需要配置 配置步骤: 1输入命令setup,选择network configuration,选择runtool,选择device configuration,选择 ...
- HDU 4499
题目大意: N*M的棋盘上摆了一些棋子,在剩余位置上尽可能多的摆上炮,使所有炮不能互吃 dfs+回溯 #include <iostream> #include <cstdio> ...
- bzoj1202:[HNOI2005]狡猾的商人 【并查集】
Description 刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的.账本上记录了n个月以来的收入情况,其中第i 个月的收入额为Ai(i=1,2,3...n-1,n), .当 ...
- as3corelib Tutorial:How to Use ArrayUtil Class in Flex
ArrayUtil class contains static utility methods for manipulating and working with Arrays. Note that ...
- 如何评价ionic和react native?
Q:对于开发hybird app首选哪个好?是ionic还是react native?如何评价ionic和react native? A: 我看好React系,React系以正确地姿势,专注地做了正确 ...
- 使用fastjson将list、map转换成json,出现$ref
这是转换时出现的问题情况( map >> json ) 引用是通过"$ref"来表示的 引用 描述 "$ref":".." 上一 ...
- IO与文件读写---Java的IO流架构
http://www.blogjava.net/pengpenglin/archive/2010/03/03/314239.html#314399 http://www.blogjava.net/jo ...