您的位置:首页 > 移动开发 > Objective-C

Object公用方法

2015-11-14 09:23 381 查看
Object方法:equals()、hashCode()、toString()、notify()、notifyAll()、finalize()、getClass()、clone()、wait()

下面看源码:

package java.lang;
public class Object {

/* 一个本地方法,具体是用C(C++)在DLL中实现的,然后通过JNI调用。*/
private static native void registerNatives();
/* 对象初始化时自动调用此方法*/
static {
registerNatives();
}
/* 返回此 Object 的运行时类。*/
public final native Class<?> getClass();

/*
hashCode 的常规协定是:
1.在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。从	某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
2.如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。
3.如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不 要求一定生成不同的整数结果。但是,程	序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。
*/
/*hashCode()是本地(native)方法,所谓本地方法就是使用其他语言(C或C++)编写的,我们可以通过本地接口(JNI)编写本地方法*/
<span style="white-space:pre">	</span>//默认的hashCode()返回的值就是对象在内存中的地址

<span style="white-space:pre">	</span>public boolean equals(Object obj) {
return (this == obj);  //默认比较地址
}

/*本地CLONE方法,用于对象的复制。*/
protected native Object <span style="font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 18px;">clone()</span> throws CloneNotSupportedException;

/*返回该对象的字符串表示。非常重要的方法*/
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());     //默认返回类名+@+hashCode的十六进制数
}

/*唤醒在此对象监视器上等待的单个线程。*/
public final native void notify();

/*唤醒在此对象监视器上等待的所有线程。*/
public final native void notifyAll();

/*在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。换句话说,此方法的行为就好像它仅执行 wait(0) 调用一样。
当前线程必须拥有此对象监视器。该线程发布对此监视器的所有权并等待,直到其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的	线程醒来。然后该线程将等到重新获得对监视器的所有权后才能继续执行。*/
public final void wait() throws InterruptedException {
wait(0);
}

/*在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量前,导致当前线程等待。*/
public final native void wait(long timeout) throws InterruptedException;

/*在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。*/
public final void wait(long timeout, int nanos) throws InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException("timeout value is negative");
}

if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}

if (nanos >= 500000 || (nanos != 0 && timeout == 0)) {
timeout++;
}

wait(timeout);
}
<span style="white-space:pre">	</span>/*GC清理对象之前所调用的清理方法,是回调方法,我们可以覆盖这个方法写一些清理的代码,GC会自动扫描没有引用的对象,即对象赋值为null;可以通过调用System.runFinalization()或System.runFinalizersOnExit()强制GC清理该对象前调用finalize()方法,GC有时不会调用对象的finalize()方法(由JVM决定)*/
/*当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。*/
protected void finalize() throws Throwable { }
}    </span>


finalize()方法:

一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用finalize()方法,并在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。
有些对象的finalize()可能都没有被运行过,可以掉用runFinalizersOnExit(Boolean value)方法来强制jvm执行垃圾清理,只要传入true值就可以了

finalize函数的应用场景
       1、当对象的使用者忘记显示释放使用资源的时候,finalize函数充当安全网的角色,相当于最后一道防火墙(祈祷finalize方法能够被及时执行);
       2、释放本地方法申请的非关键资源(程序中嵌入的其他语言申请的非关键资源,关键资源仍然要显示释放);
       3、记得在重载的finalize方法中最后调用super.finalize();系统不会自动调用

尽量避免使用finalize函数释放资源
     第一,finalize一定会被执行,但是并不总是那么及时,原因有二:
          1、垃圾回收器并不总是工作,只有当内存资源告急时,垃圾回收器才会工作;
          2、即使垃圾回收器工作,finalize方法也不一定得到执行,这是由于程序中的其他线程的优先级远远高于执行finalize()函数线程的优先级。
          因此,当finalize还没有被执行时,系统的其他资源,比如文件句柄、数据库连接池等已经消耗殆尽,造成系统崩溃。
     第二,如果一种未被捕获的异常在使用finalize方法时被抛出,这个异常不会被捕获,finalize方法的终结过程也会终止,造成对象出于破坏的状态。
     第三,垃圾回收和finalize方法的执行本身就是对系统资源的消耗,有可能造成程序的暂时停止,因此在程序中尽量避免使用finalize方法。

为什么不能显示直接调用finalize方法
      如前文所述,finalize方法在垃圾回收时一定会被执行,而如果在此之前显示执行的话,也就是说finalize会被执行两次以上,而在第一次资源已经被释放,那么在第二次释放资源时系统一定会报错,因此一般finalize方法的访问权限和父类保持一致,为protected。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: