Object公用方法
2015-11-14 09:23
381 查看
Object方法:equals()、hashCode()、toString()、notify()、notifyAll()、finalize()、getClass()、clone()、wait()
下面看源码:
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。
下面看源码:
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。
相关文章推荐
- CriticalFinalizerObject的作用
- Objective-C中的继承与多态, Category, Extension
- Objective-C 中protocol(协议)及delegate(委托、代理)
- Objective-c Category(类别)
- Objective-c 访问控制
- Objective-c 类的继承 方法重写 方法重载
- Objective-c 协议(protocol)
- Linq To Objective-C
- Objective-c @property和@Synthesize
- Objective-c 数据类型
- Objective-c 方法的调用
- Objective-c 类实现 (@implementation)
- Objective-c 类接口 (@interface) (类定义)
- Objective-c 程序结构
- Objective-c中@interface、@implementation、@protocal
- Objective-C之Meta-class和isa指针
- 关于 error: Operation is not valid due to the current state of the object。
- Object-C 字符串类各种操作方法
- Objective-C 笔记一(HelloWorld)
- Qt中的Q_OBJECT