这段代码是安全的,但是就象在错误1#那样,又作了多余的工作。Integer对象,就象String对象那样,一旦被创建就是不可变的。因此,返回内部Integer对象,而不是它的拷贝,也是安全的。* K, |6 E8 k+ G5 ?
方法getValue()应该被写为:
5 b, g' i4 k# _: |* l$ O4 L public synchronized Integer getValue()…{
9 S4 r; d2 g7 b! f( p$ O2 A, g: M // "i" is immutable, so it is safe to return it instead of a copy.
) f/ w) X | M' l. j* o$ \ return i; }- \& {( j: J, i; H8 S: k3 g8 G
Java程序比C++程序包含更多的不可变对象。JDK 所提供的若干不可变类包括:! R2 {0 o3 l1 O+ d( A- A% q
·Boolean
7 e ^: [% {* O) c x) W ·Byte
& F8 x0 x: X2 o ·Character
; ]- @: y4 k& ? ·Class
1 B% h5 M# {4 v1 c; m9 G ·Double( i6 z8 B) C* i
·Float
' ~4 t2 O- O* c7 c ·Integer' z8 C$ `+ ~' k/ o
·Long
0 ]- j, c! [& v8 g, |" ` ·Short3 H* M. d7 [" k B) n9 h! x) @
·String ·大部分的Exception的子类 四、常见错误4:自编代码来拷贝数组
4 B2 s4 [6 V0 n0 p Java允许你克隆数组,但是开发者通常会错误地编写如下的代码,问题在于如下的循环用三行做的事情,如果采用Object的clone方法用一行就可以完成:
5 J' i+ |( F) j, P0 p7 j% i public class Example…{
- O% r" W# c [0 n6 s private int[] copy;
* Y# V! R3 Y' I* p" h! u+ O /** *//*** Save a copy of "data". "data" cannot be null.*/' R: I0 x2 m* ?: p% n% {
public void saveCopy (int[] data)…{0 \3 J+ X: r' @1 C4 O; w/ q
copy = new int[data.length];
; K, e+ k# ?3 k, a for (int i = 0; i* Z* q; ~% U1 ~0 }6 W" F1 j
copy = data;
- V8 t1 y' ?# J9 L I) B } }
' K' F$ L) V9 T8 N 这段代码是正确的,但却不必要地复杂。saveCopy()的一个更好的实现是:
, Q" h4 M, n4 { P void saveCopy (int[] data)…{8 U1 ~% c: j% i* v
try…{: L: l B, W. J1 j
copy = (int[])data.clone();; k- q7 h0 }. ^" C
}catch (CloneNotSupportedException e)…{; _* T( ? g+ C* X1 u: ?
// Can"t get here.& _1 @$ s. M; e
} }
2 U$ |% g7 v# @- x, P( O; ~ 如果你经常克隆数组,编写如下的一个工具方法会是个好主意:4 q: o$ ?( z C* `, y
static int[] cloneArray (int[] data)…{
, j7 j( a; u. C0 o6 f. e+ s- m try…{* S4 L9 z2 C9 n
return(int[])data.clone();7 T/ ?# G, a& Y6 K
}catch(CloneNotSupportedException e)…{
+ h' P7 R; _4 J6 I // Can"t get here.; ~* X. c/ ^+ W1 y
} }
; r4 L7 y0 s/ E% j 这样的话,我们的saveCopy看起来就更简洁了:1 l2 b( N- X( q6 x* h6 v
void saveCopy (int[] data)…{* v. z- o9 f" ?9 q
copy = cloneArray ( data); } 五、常见错误5:拷贝错误的数据" ]6 S0 ?5 u$ t, t2 r" g
有时候程序员知道必须返回一个拷贝,但是却不小心拷贝了错误的数据。由于仅仅做了部分的数据拷贝工作,下面的代码与程序员的意图有偏差:
/ L; f3 ^8 _0 Q% @ import java.awt.Dimension;
& q' G; f5 a6 G) C" T) e# A0 j q, } /** *//*** Example class. The border="1" Height and width values should never * be |