解析Java代码经常出现的错误

来源:java认证发布时间:2012-11-12 13:15:46java认证视频

  三、常见错误3#:不必要的克隆
  我们现在知道了get方法应该返回内部数据对象的拷贝,而不是引用。但是,事情没有绝对:
  /*** Example class.The value should never * be negative.*/ public class Example{   private Integer i = new Integer (0);   public Example (){ }   /*** Set x. x must be nonnegative* or an exception will be thrown*/   public synchronized void setValues (int x) throws IllegalArgumentException{ if (x < 0)   throw new IllegalArgumentException();   i = new Integer (x);   }   public synchronized Integer getValue(){ // We can’t clone Integers so we makea copy this way. return new Integer (i.intValue());   } }
  这段代码是安全的,但是就象在错误1#那样,又作了多余的工作。Integer对象,就象String对象那样,一旦被创建就是不可变的。因此,返回内部Integer对象,而不是它的拷贝,也是安全的。
  方法getValue()应该被写为:
  public synchronized Integer getValue(){ // ’i’ is immutable, so it is safe to return it instead of a copy. return i; }
  Java程序比C++程序包含更多的不可变对象。JDK 所提供的若干不可变类包括:
  Boolean
  Byte
  Character
  Class
  Double
  Float
  Integer
  Long
  Short
  String
  大部分的Exception的子类
  四、常见错误4# :自编代码来拷贝数组
  Java允许你克隆数组,但是开发者通常会错误地编写如下的代码,问题在于如下的循环用三行做的事情,如果采用Object的clone方法用一行就可以完成:
  public class Example{ private int[] copy; /*** Save a copy of ’data’. ’data’ cannot be null.*/ public void saveCopy (int[] data){ copy = new int[data.length]; for (int i = 0; i < copy.length; ++i) copy[i] = data[i]; } }
  这段代码是正确的,但却不必要地复杂。saveCopy()的一个更好的实现是:
  void saveCopy (int[] data){ try{ copy = (int[])data.clone(); }catch (CloneNotSupportedException e){ // Can’t get here. } }
  如果你经常克隆数组,编写如下的一个工具方法会是个好主意:
  static int[] cloneArray (int[] data){ try{ return(int[])data.clone(); }catch(CloneNotSupportedException e){ // Can’t get here. } }
  这样的话,我们的saveCopy看起来就更简洁了:
  void saveCopy (int[] data){
  copy = cloneArray ( data); }
  五、常见错误5#:拷贝错误的数据
  有时候程序员知道必须返回一个拷贝,但是却不小心拷贝了错误的数据。由于仅仅做了部分的数据拷贝工作,下面的代码与程序员的意图有偏差:
  import java.awt.Dimension; /*** Example class. The height and width values should never * be negative. */ public class Example{ static final public int TOTAL_VALUES = 10; private Dimension[] d = new Dimension[TOTAL_VALUES]; public Example (){ } /*** Set height and width. Both height and width must be nonnegative * or an exception will be thrown. */ public synchronized void setValues (int index, int height, int width) throws IllegalArgumentException{ if (height < 0 || width < 0) throw new IllegalArgumentException(); if (d[index] == null) d[index] = new Dimension(); d[index].height = height; d[index].width = width; } public synchronized Dimension[] getValues() throws CloneNotSupportedException{ return (Dimension[])d.clone(); } }
  这儿的问题在于getValues()方法仅仅克隆了数组,而没有克隆数组中包含的Dimension对象,因此,虽然调用者无法改变内部的数组使其元素指向不同的Dimension对象,但是调用者却可以改变内部的数组元素(也就是Dimension对象)的内容。方法getValues()的更好版本为:
  public synchronized Dimension[] getValues() throws CloneNotSupportedException{ Dimension[] copy = (Dimension[])d.clone(); for (int i = 0; i < copy.length; ++i){ // NOTE: Dimension isn’t cloneable. if (d != null) copy[i] = new Dimension (d[i].height, d[i].width); } return copy; }
  在克隆原子类型数据的多维数组的时候,也会犯类似的错误。原子类型包括int,float等。简单的克隆int型的一维数组是正确的,如下所示:
  public void store (int[] data) throws CloneNotSupportedException{ this.data = (int[])data.clone(); // OK }
  拷贝int型的二维数组更复杂些。Java没有int型的二维数组,因此一个int型的二维数组实际上是一个这样的一维数组:它的类型为 int[]。简单的克隆int[][]型的数组会犯与上面例子中getValues()方法第一版本同样的错误,因此应该避免这么做。下面的例子演示了在克隆int型二维数组时错误的和正确的做法:
  public void wrongStore (int[][] data) throws CloneNotSupportedException{   this.data = (int[][])data.clone(); // Not OK! } public void rightStore (int[][] data){   // OK!   this.data = (int[][])data.clone();   for (int i = 0; i < data.length; ++i){ if (data != null)   this.data[i] = (int[])data[i].clone();   } }

  考试大温馨提示:本内容来源于网络,仅代表作者个人观点,与本站立场无关,仅供您学习交流使用。其中可能有部分文章经过多次转载而造成文章内容缺失、错误或文章作者不详等问题,请您谅解。如有侵犯您的权利,请联系我们,本站会立即予以处理。

视频学习

我考网版权与免责声明

① 凡本网注明稿件来源为"原创"的所有文字、图片和音视频稿件,版权均属本网所有。任何媒体、网站或个人转载、链接转贴或以其他方式复制发表时必须注明"稿件来源:我考网",违者本网将依法追究责任;

② 本网部分稿件来源于网络,任何单位或个人认为我考网发布的内容可能涉嫌侵犯其合法权益,应该及时向我考网书面反馈,并提供身份证明、权属证明及详细侵权情况证明,我考网在收到上述法律文件后,将会尽快移除被控侵权内容。

最近更新

社区交流

考试问答