Java已打消的一种特征是C的“前提编译”,它许可我们改变参数,获得分歧的行为,同时不改变其他任何代码。Java之所以丢弃了这一特征,可能是因为该特征经常在C里用于解决跨平台问题:代码的分歧部门按照具体的平台进行编译,否则不能在特定的平台上运行。因为Java的设计思惟是成为一种自动跨平台的说话,所以这种特征是没有需要的。
, g/ u" F5 O) M D2 V" g5 S5 m 然而,前提编译还有另一些很是有价值的用途。一种很常见的用途就是底时菌码。调试特征可在开发过程中使用,但在刊行的产物中却无此功能。Alen Holub提出了操作包(package)来模拟前提编译的概念。按照章矣门念,它建树了C“断定机制”一个很是有用的Java版本。之所以叫作“断定机制”,是因为我们可以说“它应该为真”或者“它应该为假”。如不美观语句分歧意你的断定,就可以发现相关的情形。这种工具在调试过程中是出格有用的。! J, n/ g3 y8 A- U
可用下面这个类进行轨范调试:
! k! p* p* K7 ]# a+ E //: Assert.java6 {# Z( G- Y3 A: I9 p
// Assertion tool for debugging
2 X1 P0 p r* ?% U0 ^* F package com.bruceeckel.tools.debug;
( j1 B# }5 G& W public class Assert {4 D5 l, O5 Q. g0 u6 ?+ F% o7 ?
private static void perr(String msg) {2 }, S3 s: `5 _" a
System.err.println(msg);
6 a: s7 Q; \$ G, _ }
7 t# r. R. V; {+ U- r' v public final static void is_true(boolean exp) {( n# B- @4 ?0 g: x2 A
if(!exp) perr("Assertion failed");
, u% ^/ K- x" @6 v2 ~ }
! m6 e, D! q, v/ V public final static void is_false(boolean exp){
0 ~& D/ L) o& r; ~5 u7 d$ @ if(exp) perr("Assertion failed");
" K' k6 [5 H) i! p8 c4 z- } }- K! n4 t+ ~2 V. i; k+ s$ I5 v
public final static void' W I& c4 t q b/ _% V/ b* v
is_true(boolean exp, String msg) {# K! o) D# i* F4 Q5 h
if(!exp) perr("Assertion failed: " + msg);3 a0 O; E+ Y" X
}
8 J' F4 A1 @+ O8 M( X% i public final static void0 y \ w1 z# c
is_false(boolean exp, String msg) {( K: ^% y9 e) D. N7 O2 F) B% s* K' M
if(exp) perr("Assertion failed: " + msg);& [! L; z1 I- l* e1 ? s
}
0 j% o$ ?0 u! [; J } ///:~
u% U Q4 C: m# V 这个类只是简单地封装了布尔测试。如不美观失踪败,就显示出犯错动静。在第9章,巨匠还会进修一个更高级的错误节制工具,名为“违例节制”。但在今朝这种情形下,perr()体例已经可以很好地工作。, v" o7 S j- _: L% y+ a& f
如不美观想使用这个类,可在自己的轨范中插手下面这一行:
8 ? o$ N- c' p% r( [& U, w& ]9 { import com.bruceeckel.tools.debug.*;
! V0 Q. A! c* c3 H 如欲断根断定机制,以便自己能刊行最终的代码,我们建树了第二个Assert类,但却是在一个分歧的包里:
: C& k0 A! R) I2 q3 g! c% V ^ //: Assert.java2 D$ V5 S/ ?4 W; j
// Turning off the assertion output
. U7 d' ~. v* h: U1 T3 U/ s // so you can ship the program.( I: Q u; J, x% q
package com.bruceeckel.tools;
. u% ~6 w; e5 K& s& W, \ public class Assert {9 U3 r8 [* h% y% B
public final static void is_true(boolean exp){}
% r- P4 p( q* G+ v! B9 i2 O) B public final static void is_false(boolean exp){} [- T1 q2 p: d# P9 l1 U$ D
public final static void; O0 D3 t8 f& C( m, k4 Y r
is_true(boolean exp, String msg) {}
/ G0 \" N: S2 O9 E: ]; _; h public final static void# U# [* q1 g$ }
is_false(boolean exp, String msg) {}
$ [# W; \2 H0 R2 |* O } ///:~
' h+ U/ O4 a# v 此刻,假如将前一个import语句酿成下面这个样子:( a$ Q9 H1 d s" W: m: Q) M4 ^2 p
import com.bruceeckel.tools.*;. o0 X5 r [+ T
轨范便不再显示出断言。下面是个例子:5 @ w0 h$ w; ~( i- d/ I
//: TestAssert.java
# Z* k6 l( h5 x8 e- l // Demonstrating the assertion tool; I4 c. a1 L, N) v. z
package c05;
6 r" S3 m# p0 V# F( V0 L. U // Comment the following, and uncomment the* w) G, H' b" N( v3 e/ i
// subsequent line to change assertion behavior:
4 `% p1 D) i' A C( R, g6 m9 q. ] import com.bruceeckel.tools.debug.*;
8 H! f% k) b7 r // import com.bruceeckel.tools.*;
5 L( ]& E3 E) m# U' n public class TestAssert {
5 b J! K# R8 O: G' ~; L y3 N public static void main(String[] args) {
2 I& t/ w3 I) C" e1 o% l Assert.is_true((2 + 2) == 5);) ^9 { Z. |0 P7 ^
Assert.is_false((1 + 1) == 2);7 |! b6 ?, f9 F I
Assert.is_true((2 + 2) == 5, "2 + 2 == 5");- N% d8 q9 w; P4 z2 ^& T
Assert.is_false((1 + 1) == 2, "1 +1 != 2");1 J' B8 z; ^8 @
}
4 ?& I( A$ r/ y! M: q } ///:~
+ F* J: W! J2 C- E+ [5 i6 j+ J% [4 F 经由过程改变导入的package,我们可将自己的代码年夜调试版本酿成最终的刊行版本。这种手艺可应用于任何种类的前提代码。 |