</p> 当你对某个对象不再感乐趣,也就是它可以被断根时,这个对象应该处于某种状况,使它占用的内存可以被平安地释放。例如,若是对象代表了一个打开的文件,在对象被收受接管前途序员应该封锁这个文件。只要对象中存在没有被恰当断根的部门,你的轨范就存在很隐晦的错误。finalize( )的价质ё仝于可以用来最终发现这种情形,尽管它并不老是会被挪用。如不美观某次
% ~9 I; E1 y, X; W, Z finalize( )的动作使得bug被发现,那你就可据此找出问题地址——这才是你真正关心的。
. l/ A+ h5 M' H4 V# N 以下是个简单的例子,示范了可能的使用体例:
3 d) ~+ A9 }% `; J C( O+ J: u class Book {* q4 Z# ]- X; F- D
boolean checkedOut = false;9 V) K y4 k. l" c8 m
Book(boolean checkOut) {* H# O* _8 B) z- ^8 d
checkedOut = checkOut;1 F3 J2 n. j3 r
}
2 \" ?* U0 {- L& ? void checkIn() {
8 y& t5 T9 i* a' F% Y7 j6 q checkedOut = false;$ W) P$ K; y% g! o& j
}$ T. Z* I, U, e( l
public void finalize() {
8 M2 W) U- [/ l0 k; a# q6 H- L8 Q if(checkedOut), f* V* v% s/ T$ R( ^" s
System.out.println("Error: checked out");2 v, I G f7 R3 G, J( t( P
// Normally, you'll also do this:7 [+ K! M& j/ h S5 l0 W
// super.finalized();
6 g+ S2 Z# N4 n" M% M0 |* t" ^* Z }
& V/ G( [7 h% U* B3 ` }' S: v9 e' K4 j* T/ a8 m) ?0 \4 r
public class TerminationCondition {
1 s, j! ^) t# }; l/ G public static void main(String[] args) {6 J& U& |$ h/ b) F% q% w6 [) a
Book novel = new Book(true);0 p/ i" L) d8 @% G2 W
// Proper cleanup:
% C- y! q$ D% f( v F( K! P' K7 ]! h novel.checkIn();9 w1 |1 l: z" H" ^" j
// Drop the reference, forget to clean up:
) k f I' W; \' T new Book(true);
% \. T5 }, h9 S V$ N9 ~% m, g // Force garbage collection & finalization:
+ m0 \6 H/ J. k System.gc();
0 u7 b* L- }6 J' Z& P& M* B }+ [4 M/ l9 I, l' I$ Y: p
}
2 p- W; F/ r/ S$ _; i 本例的终结前提是:所有的Book对象在被算作垃圾收受接管前都应该被签入(check in)。但在main( )体例中,因为轨范员的错误,有一本书未被签入。若是没有 finalize( )来验证终结前提,将很难发现这种错误。
: p4 _, n- _( P8 a 注重,System.gc( )用于强制终结动作的进行。即使不这么做的话,经由过程一再的执行轨范(假设轨范将分配年夜量的存储空间而导致垃圾收受接管动作的执行),最终也能找犯错误的Book对象。 |