{
// OK!
this.data = (int[][])data.clone();
for (int i = 0; i < data.length; ++i){
if (data != null)
this.data[i] = (int[])data[i].clone();
}
}
六、常见错误6#:检查new 操作的结果是否为null
Java编程新手有时候会检查new操作的结果是否为null。可能的检查代码为: Integer i = new Integer (400); if (i == null) throw new NullPointerException(); 检查当然没什么错误,但却不必要,if和throw这两行代码完全是浪费,他们的唯一功 用是让整个程序更臃肿,运行更慢。C/C++程序员在开始写java程序的时候常常会这么做, 这是由于检查C中malloc()的返回结果是必要的,不这样做就可能产生错误。检查C++中 new操作的结果可能是一个好的编程行为,这依赖于异常是否被使能(许多编译器允许异常 new 操作不允许返回null, 被禁止, 在这种情况下new操作失败就会返回null)。 在java 中, 如果真的返回null,很可能是虚拟机崩溃了,这时候即便检查返回结果也无济于事。
七、常见错误7#:用== 替代.equals
在Java中,有两种方式检查两个数据是否相等:通过使用==操作符,或者使用所有对 象都实现的.equals方法。原子类型(int, flosat, char 等)不是对象,因此他们只能使用==操作 符,如下所示: int x = 4;
int y = 5;
if (x == y)
System.out.println ("Hi");
// This ’if’ test won’t compile.
if (x.equals (y))
System.out.println ("Hi");
对象更复杂些,==操作符检查两个引用是否指向同一个对象,而equals方法则实现更 专门的相等性检查。 更显得混乱的是由java.lang.Object 所提供的缺省的equals方法的实现使用==来简单的 判断被比较的两个对象是否为同一个。 许多类覆盖了缺省的equals方法以便更有用些,比如String类,它的equals方法检查 两个String对象是否包含同样的字符串, 而Integer的equals方法检查所包含的int值是否相 等。大部分时候,在检查两个对象是否相等的时候你应该使用equals方法,而对于原子类 型的数据,你用该使用==操作符。
八、常见错误8#: 混淆原子操作和非原子操作
Java保证读和写32位数或者更小的值是原子操作,也就是说可以在一步完成,因而不 可能被打断,因此这样的读和写不需要同步。以下的代码是线程安全(thread safe)的: public class Example{ private int value; // More code here... public void set (int x){ // NOTE: No synchronized key
word this.value = x; } } 不过,这个保证仅限于读和写,下面的代码不是线程安全的: public void increment (){ // This is effectively two or three instructions: // 1) Read current setting of ’value’. // 2) Increment that setting. // 3) Write the new setting back. ++this.value;