一、Object类是全部java类的基类html
若是在类的声明中未使用extends关键字指明其基类,则默认基类为Object类,ex:java
public class Person{程序员
~~~~~编程
}api
等价于数组
public class Person extends Object{多线程
~~~~~app
}编程语言
二、Object类之equals方法ide
①、Object类中定义有:
public boolean equals(Object obj)方法。
提供定义对象是否相等的逻辑。
②、Objec的equals方法 定义为:x.equals(y)当x和y是同一个对象的应用时返回true,不然返回false.
③、J2SDK提供的一些类,如String,Date等,重写了Object的equals()方法,调用这些类的equals方法,x.equals(y),当x和y所引用的是同一类对象且属性内容相等时(并不必定是相等的对象),返回true不然返回false.
④、能够根据须要在用户的自定义类型中重写equals()方法。
public class TestEquals{ public static void main (String args[]){ Cat cat1 = new Cat(1,2,3); Cat cat2 = new Cat(1,2,3); System.out.println(cat1 == cat2); System.out.println(cat1.equals(cat2 )); String s1 = new String("hello"); String s2 = new String("hello"); System.out.println(s1 == s2); System.out.println(s1.equals(s2)); } } class Cat{ int color; int height,weight; Cat(int color , int height , int weight){ this.color= color; this.height = height; this.weight = weight; } public boolean equals(Object obj){ if(obj == null) return false; else{ if( obj instanceof Cat){ Cat c = (Cat)obj; if(c.color == this.color && c.height == this.height && c.weight == this.weight){ return true; } } } return false; } }
运行结果:
[size=small] 在根类Object中包含一下方法:
咱们知道全部的类都是继承于Object,因此咱们编写的类默认都具备这些方法,究竟这些方法作什么用,须要让全部的对象都拥有,我将一一来解释。
首先你们要明白回调(callback)方法,所谓回调方法就是程序在运行特定功能时JVM会自动调动这些方法,假设你使用System.out.print(obj)打印出对象obj信息,则运行时JVM会自动调用obj对象的toString()方法,toString()方法就是回调方法。理解回调方法后,下面咱们来看这些方法:
[list]
[*]equals()、toString()和hashCode():这两个方法主要用于比较两个对象是否相等,查看Object源代码(要多查看源代码便于本身理解)知道,默认的equals()是:
,
==只有当两个对象地址相同时才返回true,因此默认的equals()方法根本没什么用,由于对象在内存中的地址(基本类型不一样)确定不一样的;因此咱们编写类时最好覆盖默认的equals()、hashCode()和toString()方法(查看JDK中的类也大部分覆盖了这些方法),默认的hashCode()返回的值就是对象在内存中的地址,而默认的toString()方法就是打印出对象的地址,toString()和equals()方法内部是经过hashCode()的返回值来实现的,hashCode()是本地(native)方法,所谓本地方法就是使用其余语言(C或C++)编写的,咱们能够经过本地接口(JNI)编写本地方法;
Object——equals的应用
1、概述:
Object类是全部Java类的祖先。每一个类都使用 Object 做为超类。全部对象(包括数组)都实现这个类的方法。
在不明确给出超类的状况下,Java会自动把Object做为要定义类的超类。
可使用类型为Object的变量指向任意类型的对象。
Object类有一个默认构造方法pubilc Object(),在构造子类实例时,都会先调用这个默认构造方法。
Object类的变量只能用做各类值的通用持有者。要对他们进行任何专门的操做,都须要知道它们的原始类型并进行类型转换。例如:
Object obj = new MyObject();
MyObject x = (MyObject)obj;
2、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() 方法,或者其余某个线程中断当前线程,或者已超过某个实际时间量。
3、方法使用说明
一、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方法。
二、toString():返回该对象的字符串表示。Object类中的toString()方法会打印出类名和对象的内存位置。几乎每一个类都会覆盖该方法,以便打印对该对象当前状态的表示。大多数(非所有)toString()方法都遵循以下格式:类名[字段名=值,字段名=值...],固然,子类应该定义本身的toString()方法。例如:
public String toString(){
reurn "Employee[name=" + name + ",salary=" + salary + ",hireDay=" + hireDay + "]";
}
toString()方法是很是重要的调试工具,不少标准类库中的类都定义了toString()方法,以便程序员得到有用的调试信息。
4、来自SUN公司的java.long.Object类的API文档,网上有chm中文版的,很好找。为了查阅方便,我从SUN公司的JavaDoc站点上复制出来了Object类的API文档。
java.lang.Object
public class Object
类 Object
是类层次结构的根类。每一个类都使用 Object
做为超类。全部对象(包括数组)都实现这个类的方法。
Class
构造方法摘要 | |
---|---|
Object() |
方法摘要 | |
---|---|
protected Object |
clone() 建立并返回此对象的一个副本。 |
boolean |
equals(Object obj) 指示某个其余对象是否与此对象“相等”。 |
protected void |
finalize() 当垃圾回收器肯定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。 |
Class<? extendsObject> |
getClass() 返回一个对象的运行时类。 |
int |
hashCode() 返回该对象的哈希码值。 |
void |
notify() 唤醒在此对象监视器上等待的单个线程。 |
void |
notifyAll() 唤醒在此对象监视器上等待的全部线程。 |
String |
toString() 返回该对象的字符串表示。 |
void |
wait() 致使当前的线程等待,直到其余线程调用此对象的 notify() 方法或 notifyAll() 方法。 |
void |
wait(long timeout) 致使当前的线程等待,直到其余线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量。 |
void |
wait(long timeout, int nanos) 致使当前的线程等待,直到其余线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其余某个线程中断当前线程,或者已超过某个实际时间量。 |
构造方法详细信息 |
---|
public Object()
方法详细信息 |
---|
public final Class<? extends Object> getClass()
java.lang.Class
对象。此结果属于类型
Class<? extends X>
,其中 X 表示清除表达式中的静态类型,该表达式调用
getClass
。
public int hashCode()
java.util.Hashtable
提供的哈希表。
hashCode
的常规协定是:
hashCode
方法都必须生成相同的整数结果。equals(java.lang.Object)
方法,两个对象不相等,那么在两个对象中的任一对象上调用 hashCode 方法一定会生成不一样的整数结果。可是,程序员应该知道,为不相等的对象生成不一样整数结果能够提升哈希表的性能。实际上,由 Object 类定义的 hashCode 方法确实会针对不一样的对象返回不一样的整数。(这通常是经过将该对象的内部地址转换成一个整数来实现的,可是 JavaTM 编程语言不须要这种实现技巧。)
equals(java.lang.Object)
,
Hashtable
public boolean equals(Object obj)
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
。Object
类的 equals 方法实现对象上差异可能性最大的相等关系;即,对于任何非空引用值 x
和 y
,当且仅当x
和 y
引用同一个对象时,此方法才返回 true
(x == y
具备值 true
)。
注意:当此方法被重写时,一般有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具备相等的哈希码。
obj
- 要与之比较的引用对象。
true
;不然返回
false
。
hashCode()
,
Hashtable
protected Object clone() throws CloneNotSupportedException
是正确的,则表达式:x.clone() != x
将为 true,但这些不是绝对条件。通常状况下是:x.clone().getClass() == x.getClass()
将为 true,但这不是绝对条件。x.clone().equals(x)
按照惯例,返回的对象应该经过调用 super.clone 得到。若是一个类及其全部的超类(Object 除外)都遵照此约定,则 x.clone().getClass() == x.getClass()。
按照惯例,此方法返回的对象应该独立于该对象(正被克隆的对象)。要得到此独立性,在 super.clone 返回对象以前,有必要对该对象的一个或多个字段进行修改。这一般意味着要复制包含正在被克隆对象的内部“深层结构”的全部可变对象,并使用对副本的引用替换对这些对象的引用。若是一个类只包含基本字段或对不变对象的引用,那么一般不须要修改 super.clone 返回的对象中的字段。
Object 类的 clone 方法执行特定的克隆操做。首先,若是此对象的类不能实现接口 Cloneable,则会抛出CloneNotSupportedException。注意:全部的数组都被视为实现接口 Cloneable。不然,此方法会建立此对象的类的一个新实例,并像经过分配那样,严格使用此对象相应字段的内容初始化该对象的全部字段;这些字段的内容没有被自我克隆。因此,此方法执行的是该对象的“浅表复制”,而不“深层复制”操做。
Object 类自己不实现接口 Cloneable,因此在类为 Object 的对象上调用 clone 方法将会致使在运行时抛出异常。
CloneNotSupportedException
- 若是对象的类不支持
Cloneable
接口,则重写
clone
方法的子类也会抛出此异常,以指示没法克隆某个实例。
Cloneable
public String toString()
toString
方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂。建议全部子类都重写此方法。
Object
类的 toString
方法返回一个字符串,该字符串由类名(对象是该类的一个实例)、at 标记符“@
”和此对象哈希码的无符号十六进制表示组成。换句话说,该方法返回一个字符串,它的值等于:
getClass().getName() + '@' + Integer.toHexString(hashCode())
public final void notify()
wait
方法,在对象的监视器上等待。
直到当前的线程放弃此对象上的锁定,才能继续执行被唤醒的线程。被唤醒的线程将以常规方式与在该对象上主动同步的其余全部线程进行竞争;例如,唤醒的线程在做为锁定此对象的下一个线程方面没有可靠的特权或劣势。
此方法只应由做为此对象监视器的全部者的线程来调用。经过如下三种方法之一,线程能够成为此对象监视器的全部者:
synchronized
语句的正文。Class
类型的对象,能够经过执行该类的同步静态方法。一次只能有一个线程拥有对象的监视器。
IllegalMonitorStateException
- 若是当前的线程不是此对象监视器的全部者。
notifyAll()
,
wait()
public final void notifyAll()
wait
方法,在对象的监视器上等待。
直到当前的线程放弃此对象上的锁定,才能继续执行被唤醒的线程。被唤醒的线程将以常规方式与在该对象上主动同步的其余全部线程进行竞争;例如,唤醒的线程在做为锁定此对象的下一个线程方面没有可靠的特权或劣势。
此方法只应由做为此对象监视器的全部者的线程来调用。请参阅 notify
方法,了解线程可以成为监视器全部者的方法的描述。
IllegalMonitorStateException
- 若是当前的线程不是此对象监视器的全部者。
notify()
,
wait()
public final void wait(long timeout) throws InterruptedException
notify()
方法或
notifyAll()
方法,或者超过指定的时间量。
当前的线程必须拥有此对象监视器。
此方法致使当前线程(称之为 T)将其自身放置在对象的等待集中,而后放弃此对象上的全部同步要求。出于线程调度目的,线程 T 被禁用,且处于休眠状态,直到发生如下四种状况之一:
中断
线程 T。在没有被通知、中断或超时的状况下,线程还能够唤醒一个所谓的虚假唤醒 (spurious wakeup)。虽然这种状况在实践中不多发生,可是应用程序必须经过如下方式防止其发生,即对应该致使该线程被提醒的条件进行测试,若是不知足该条件,则继续等待。换句话说,等待应老是发生在循环中,以下面的示例:
synchronized (obj) { while (<condition does not hold>) obj.wait(timeout); ... // Perform action appropriate to condition }(有关这一主题的更多信息,请参阅 Doug Lea 撰写的《Concurrent Programming in Java (Second Edition)》(Addison-Wesley, 2000) 中的第 3.2.3 节或 Joshua Bloch 撰写的《Effective Java Programming Language Guide》(Addison-Wesley, 2001) 中的第 50 项。
若是当前线程在等待时被其余线程中断
,则会抛出 InterruptedException。在按上述形式恢复此对象的锁定状态时才会抛出此异常。
注意,因为 wait 方法将当前的线程放入了对象的等待集中,因此它只能解除此对象的锁定;能够同步当前线程的任何其余对象在线程等待时仍处于锁定状态。
此方法只应由做为此对象监视器的全部者的线程来调用。请参阅 notify
方法,了解线程可以成为监视器全部者的方法的描述。
timeout
- 要等待的最长时间(以毫秒为单位)。
IllegalArgumentException
- 若是超时值为负。
IllegalMonitorStateException
- 若是当前的线程不是此对象监视器的全部者。
InterruptedException
- 若是在当前线程等待通知以前或者正在等待通知时,另外一个线程中断了当前线程。在抛出此异常时,当前线程的
中断状态 被清除。
notify()
,
notifyAll()
public final void wait(long timeout, int nanos) throws InterruptedException
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 }此方法只应由做为此对象监视器的全部者的线程来调用。请参阅
notify
方法,了解线程可以成为监视器全部者的方法的描述。
timeout
- 要等待的最长时间(以毫秒为单位)。
nanos
- 额外时间(以毫微秒为单位,范围是 0-999999)。
IllegalArgumentException
- 若是超时值是负数,或者毫微秒值不在 0-999999 范围内。
IllegalMonitorStateException
- 若是当前线程不是此对象监视器的全部者。
InterruptedException
- 若是在当前线程等待通知以前或者正在等待通知时,其余线程中断了当前线程。在抛出此异常时,当前线程的
中断状态 被清除。
public final void wait() throws InterruptedException
notify()
方法或
notifyAll()
方法。换句话说,此方法的行为就好像它仅执行
wait(0) 调用同样。
当前的线程必须拥有此对象监视器。该线程发布对此监视器的全部权并等待,直到其余线程经过调用 notify
方法,或 notifyAll
方法通知在此对象的监视器上等待的线程醒来。而后该线程将等到从新得到对监视器的全部权后才能继续执行。
对于某一个参数的版本,实现中断和虚假唤醒是可能的,并且此方法应始终在循环中使用:
synchronized (obj) { while (<condition does not hold>) obj.wait(); ... // Perform action appropriate to condition }此方法只应由做为此对象监视器的全部者的线程来调用。请参阅
notify
方法,了解线程可以成为监视器全部者的方法的描述。
IllegalMonitorStateException
- 若是当前的线程不是此对象监视器的全部者。
InterruptedException
- 若是在当前线程等待通知以前或者正在等待通知时,另外一个线程中断了当前线程。在抛出此异常时,当前线程的
中断状态 被清除。
notify()
,
notifyAll()
protected void finalize() throws Throwable
finalize
方法,以配置系统资源或执行其余清除。
finalize 的常规协定是:当 JavaTM 虚拟机已肯定还没有终止的任何线程没法再经过任何方法访问此对象时,将调用此方法,除非因为准备终止的其余某个对象或类的终结操做执行了某个操做。finalize 方法能够采起任何操做,其中包括再次使此对象对其余线程可用;不过,finalize 的主要目的是在不可撤消地丢弃对象以前执行清除操做。例如,表示输入/输出链接的对象的 finalize 方法可执行显式 I/O 事务,以便在永久丢弃对象以前中断链接。
Object 类的 finalize 方法执行非特殊性操做;它仅执行一些常规返回。Object 的子类能够重写此定义。
Java 编程语言不保证哪一个线程将调用某个给定对象的 finalize 方法。但能够保证在调用 finalize 时,调用 finalize 的线程将不会持有任何用户可见的同步锁定。若是 finalize 方法抛出未捕获的异常,那么该异常将被忽略,而且该对象的终结操做将终止。
在启用某个对象的 finalize 方法后,将不会执行进一步操做,直到 Java 虚拟机再次肯定还没有终止的任何线程没法再经过任何方法访问此对象,其中包括由准备终止的其余对象或类执行的可能操做,在执行该操做时,对象可能被丢弃。
对于任何给定对象,Java 虚拟机最多只调用一次 finalize 方法。
finalize
方法抛出的任何异常都会致使此对象的终结操做中止,但能够经过其余方法忽略它。
Throwable
- 此方法抛出的
Exception