object类的理解
Object类学习
在学习java的过程中,自己定义的类总会调用一些不知道哪里来的方法,而这些方法都来着与object类,为了能够更好的使用object为我们提供的方法,我们应该学习一下object对象的一些方法,加深理解。
public class Object {
/**
* 构造方法 Constructs a new object.
*/
@HotSpotIntrinsicCandidate
public Object() {}
/**
* 返回this的运行时class
* 实际返回的类型是调用getClass后(Class<? extends |X|>)静态类型擦除(|X|)的结果
*/
public final native Class<?> getClass();
/**
* 默认返回对象的内存地址
* 对象的equals相等必须返回相同的hashCode
* 在一个程序中如果用于比较equals的信息没有改变,那么返回的hashCode也应该是不变的
*/
public native int hashCode();
/**
* 指示某个其他对象是否“等于”此对象
* Object方法默认实现时对比hashCode是否相等(即内存中是否为同一对象)
* 重写equals方法一般必须重写hashCode方法,“相等”的对象必须拥有相同的hashCode
* equals方法在non-null对象引用上实现了等价关系
* 1.自反:x.equals(x) == ture
* 2.对称:只有当x.equasl(y) == true 时, y.equals(x) 才应该返回true
* 3.传递: x.equas(y) == true 并且 y.equals(z) == true ,则 x.equasl(z)也应该 返回true
* 4.一致: 在未修改比较所用信息时,多次调用x.equals(y)应该返回相同的结果
* 5.非空: x.equals(null) 应该返回false
*/
public boolean equals(Object obj) {
return (this == obj);
} /**
* 创建并返回此对象的副本
* “复制”的精确含义取决于对象的类别,一般对于对于对象X有:
* 1.x.clone()!=x
* 2.x.clone().getClass() == x.getClass()
* 3.x.clone().equals(x) == true
* 4.x.clone() 一般会调用 super.clone() 来获得
* 独立性:一般x'=x.clone(), x'与x无关 。所以可能需要修改 super.clone()返回对象的一个或多个字段(使用副本引用代替“深层结构”的可变对象引用)
* 如果类没有实现Cloneable,将抛出CloneNotSupportedException,所有的数组(T[])都实现了CloneAble接口,并且返回类型是T[] (T是任何引用类型或基本类型)
* 如果此方法创建的x'新实例使用x响应的字段内容初始化其所有字段为“浅拷贝”非“深拷贝”
*/ protected native Object clone() throws CloneNotSupportedException; /**
* 返回对象的字符串表示形式,应该 简洁但信息丰富 便于阅读 建议所有子类覆盖
* 默认实现:类名称+@+哈希吗十六进制
*/ public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } /**
* 唤醒正在等待该对象监视器的单个线程
* 如果线程正在等待此对象,则随机唤醒其中一个,线程通常调用wait()方法之一等待对象的监视器
* 被唤醒的线程将以通常的方式主动竞争此对象的监视器
* 此方法只能由此对象的监视器拥有者线程调用,获取监视器的三种方式:
* 1.执行该对象的 synchronized 实例方法
* 2.执行该对象的synchronized 代码块
* 3.Class类型的对象通过执行该类的synchronized静态方法
* 一次只能又一个对象用于对象的监视器 * IllegalMonitorStateException 非法监视器状态异常如果线程没有拥有监视器调用此方法
*/ public final native void notify(); /**
* 唤醒等待此对象监视器的所有线程
* 线程通过调用wait()方法之一等待此对象的监视器
* 被唤醒的线程将以通常的方式主动竞争此对象的监视器
* 参考 notify()方法
*/ public final native void notifyAll(); /**
* 造成当前线程等待 直到另外一个线程调用:notify()、notifyAll()或者超过指定时间 * 当前线程必须拥有此对象的监视器
* 导致当前线程:T 处于对象的等待集中,然后放弃所有的同步声明(放弃持有的监视器)线程被禁止调度 处于休眠状态,以下四种方法将改变休眠状态:
* 1.其他线程调用此对象的notify()方法,且此对象正好被唤醒
* 2.其他线程调用此对象的notigyAll()方法
* 3.其他线程中断(Thread.interrup())了 T
* 4.指定的等待时间已经结束,如果指定的等待时间为0则不考虑超时,只是待唤醒
* 然后从该对象的等待集中删除此线程:T,并且重新启用线程调度,以通常的方式进行竞争 * 一旦T获取了对象的对象的控制权对象上的所有同步声明都将恢复现状(即:调用wait()方法时的情况),然后T从wait()方法返回,因此返回时此对象和T的同步状态与调用wait()方法时相同
* 一次只能又一个对象用于对象的监视器 * 线程可以在没有notified、interrupted、timing out 的情况被“虚假唤醒”,应该防范并继续等待 * 如果当前线程被其他线程中断(Thread.interrupt())则抛出InterruptedException 并清除中断状态,恢复锁状态之前不会抛出此异常(什么情况) * 建议在while中检查等待条件,防止虚假唤醒可能导致的问题 * IllegalMonitorStateException 非法监视器状态异常如果线程没有拥有监视器调用此方法
*/public final void wait(long timeoutMillis, int nanos) throws InterruptedException { if (timeoutMillis < 0) { throw new IllegalArgumentException("timeoutMillis value is negative"); } if (nanos < 0 || nanos > 999999) { throw new IllegalArgumentException( "nanosecond timeout value out of range"); } if (nanos > 0) { timeoutMillis++; } wait(timeoutMillis);} /**
* 造成当前线程等待 直到另外一个线程调用:notify()、notifyAll()、Thread.interrupt()或者超过指定时间 * 参考wait(long,int)
* 导致当前线程:T 处于对象的等待集中,然后放弃所有的同步声明(放弃持有的监视器)线程被禁止调度 处于休眠状态,以下四种方法将改变休眠状态:
* * IllegalMonitorStateException 非法监视器状态异常如果线程没有拥有监视器调用此方法
*/ public final native void wait(long timeoutMillis) throws InterruptedException; /**
* 造成当前线程等待 直到notified、interrupted * 参考wait(long,int)
* 导致当前线程:T 处于对象的等待集中,然后放弃所有的同步声明(放弃持有的监视器)线程被禁止调度 处于休眠状态,以下四种方法将改变休眠状态:
* * IllegalMonitorStateException 非法监视器状态异常如果线程没有拥有监视器调用此方法
*/ public final void wait() throws InterruptedException { wait(0L); } /**
* 当垃圾收集器确认此对象没有更多引用时,由垃圾收集器调用 。子类重写finalize()方法可以处理系统资源或其他清理 * 通常的约定是当VM确认没有任何方法可以通过未死亡的线程访问到此对象时
* finalize()方法可以采取任何行动,包括使自己再次被其他对象可访问,但是通常的目的是在对象被不可撤销的销毁前执行清理操作如:I/O断开连接等
* Object.finalize()方法没有任何特殊处理,子类可以重写
* java不保证哪个线程将调用任何对象的finalize()方法,但是保证调用finalize()方法的线程不会持有任何用户可见的锁
* 一个对象的finalize()方法被调用后,不会被再次调用
* jvm永远不会调用用一个对象的finalize()方法多次
* 异常将导致对象的销毁被终止,但异常会被忽略 * 类对于嵌入的non-heap资源有许多清除操作,确保实例的声明周期比资源要长 java.ref.Reference.reachablityFence 确保可以资源正在使用时,仍可访问 * 子类应该避免覆盖finalise()方法除非在销毁前必须清理non-heap资源
* 和constructors不同finalize不会自动链式调用,所以需要显示调用supper.finalise,并且为了防止过早终结finalize链应该在try-finally块中确保始终调用 * 终结机制存在本质上的问题,可能导致:性能问题、死锁、和挂起 * 终结器中的错误可能导致资源泄露,并且无法取消 * 不同对象的finalise方法没有指定排序,且无法保证最终确定的时间 * 建议:还有non-heap资源的类应该提供方法以显示释放资源,并且如果有可能应该实现:AutoCloseable。Cleaner、PhantomReference提供了更有效的方法释放无法访问对象的资源
*/ protected void finalize() throws Throwable { }