Object 中的默认方法
1.public final native Class<?> getClass()
getClass方法,返回该实例的java.lang.Class类,例如
Object obj = new Solution();
System.out.print(obj.getClass());
输出为
class Solution
2.public native int hashCode()
返回一个对象的哈希值。
无论在java程序运行时这个对象被调用多少次,如果该对象中的信息没修改的话,该方法都返回同一个int值。如果调用equal方法两个对象相等,那么调用它们hashcode方法返回的int值也相等。如果调用equal方法两个对象不等,它们的hashcode不一定不等,在它们不等时返回不同的hashcode可以提高hashtable的性能。
3.public boolean equals(Object obj)
表明这个对象是否和其他对象相等。对于非空对象引用有如下性质:
(1). 反身性 x.equals( x ) return true
(2). 对称性 x.equals( y ) 在有且只有y.equals(x) return ture 的情况下 return true
(3).传递性 如果x.equals( y ) return true 并且 y.equls( z ) return true,那么x.equals(z) return true
(4).一致性 只要对象信息没有被修改,无论多少次调用x.equals(y) 结果都是一致的。
当需要重写equals方法时,最好也重写hashcode方法,保证两个对象相等时hashcode返回的int值相等。
4.protected native Object clone()
创建并返回一个该对象的拷贝,对于任意对象:
1. x.clone() != x return true;
2.x.clone().getClass() == x.getClass() return true;
3.x.clone().equals(x) return true ; 但这并不是绝对必须的
4.如果一个类并且所有它的父类都调用super.clone() ,那么有x.clone().getClass() == x.getClass()
5.按照惯例,克隆的对象和被克隆对象应该是独立的,为了实现这种独立性,可能需要修改clone返回对象的一个或多个字段,在克隆任何可变的具有深层结构的对象时,会将引用指向其拷贝。如果类只包含基本类型或者指向不可变对象的引用,那么super.clone()方法返回的对象中的属性不会改变。
6.具体操作是:
(1)如果该类没有实现Cloneable接口,那么抛出CloneNotSupportedException异常。
(2)所有的数组类型实现了Cloneable接口,返回T[]类型。
(3)然而这个方法创建了这个类的实例并使用和它对应属性初始化了该实例对应的所有属性,这些属性自身没有被克隆,所以clone()默认方法是浅拷贝的。
(4)Object本身并没有实现Cloneable接口,调用clone()会抛异常。
5.public String toString()
返回一串代表该类实例的字符串,这个字符串简介并具有带表性,可以让用户很容易理解。
建议所有子类重写该方法。默认输出为getClass().getName()+’@’+Integer.toHexString(hashCode())。
6.public final native void notify()
唤醒单个在监视并等待这个对象的线程。如果一些线程在等待这个对象,则选择其中一个并唤醒它。
在当前线程放弃这个对象的锁之前唤醒的线程不能够运行,唤醒的线程会在其他线程完成对这个对象的同步后完成。
这个方法只能被拥有该对象的监视器的线程调用,一个成为该方法监视器的线程有以下三种方法之一:
(1)通过执行一个该对象的同步实例方法。
(2)通过执行一个使该对象同步的同步体声明。
(3)Class类的对象通过执行作用在该类的静态同步方法。
7.public final native void notifyAll()
唤醒所有等待该对象的监视器,其他与notify相同。
8.public final native void wait(long timeout)
使当前线程处于等待状态直到其他线程调用该对象的notify()或notifyAll()方法,或者一个特定时间到期后。
当前线程一定要拥有该对象的监视器。
这个方法导致这个当前线程(称为T)将自己放入这个对象的等待集合,然后让出部分或所有对这个对象的同步要求。然后T在线程调度用途方面变得没有能力并进入休眠直到以下四个事件中一个发生:
(1)其他线程调用该对象的notify()方法,而线程T恰好被选到称为唤醒的线程。
(2)一些其他的线程调用该对象的notifyAll()方法。
(3)一些其他线程中断线程T( Thread.interrupt() )
(4)指定时间耗尽,如果输入的timeout时间为0,则该超时时间不考虑在内,然后线程会等待直到被唤醒。
然后线程T会从该对象的等待集合中移除,然后让T重新获取线程调度的权利。然后和其他线程通过通常的方法去竞争地获取该对象的同步权利。一旦获取了这个对象的使用权利,它所有的在该对象的同步要求都被恢复到现状。那就是说,在当wait()被调用后,然后线程T从wait()调用中返回,这时候,这个对象的同步状态和线程T的状态就和调用wait()前的状态一样。
线程也可以不被notified方法、中断或者超时唤醒,即所谓的“虚假唤醒”。虚假唤醒实际上并不常见,应用程序必须通过测试线程唤醒条件来避免虚假唤醒,如果条件不满足应该持续等待。换句话说,wait应该总是出现在循环之中,比如:
synchronized(obj) {
while ( condition does not hold ) {
obj.wait(timeout);
}
}
如果当前线程在等待前或等待时被中断,那么会抛出一个InterruptedException。这个异常直到恢复到以上状态才不会抛出。
wait()会将当前想成加入到这个对象的等待集合中,只会放弃这个对象的锁,此时在这个线程的其他对象可能仍然拥有同步锁。
这个方法只能被拥有这个对象的监视器的线程调用。
9.public final void wait(long timeout,int nanos)
这个方法和上面的一个参数wait很像,但是它允许更精准的时间来等待notify,等待时长为1000000*timeout + nanos 纳秒。
10.public final void wait()
与wait(0)相同。
11.protected void finalize()
垃圾收集器作用于一个对象时,当垃圾收集器确定没有引用指向这个对象。它子类重写的这个方法会处理系统资源或者进行其他清理。
可以在使对象重新被一些线程使用。通常的作用是在回收时手动进行一些清理工作。
Object对象的finalize方法没有任何作用,方法里直接返回。
Java并不保证哪个线程会调用finalize方法,但它保证线程调用finalize方法不会持有任何用户可见的同步锁。如果一个未捕获的异常被finalize抛出,这个异常将会被忽略,终结将会结束。
在finalize方法被调用后,如果当虚拟机确定没有其他线程在能够访问这个对象后,便没有额外的动作执行。