軟件構造複習中關於不變性的一個疑問以及代碼驗證

  在查看MIT的軟件構造講義時,我發現有一個練習以下:數組

    /** Represents an immutable right triangle. */
      class RightTriangle {
/*A*/     private double[] sides;

/*B*/     public final int hypotenuse = 2;

          /** Make a right triangle.
           * @param legA, legB  the two legs of the triangle
           * @param hypotenuse    the hypotenuse of the triangle.
 *C*       *        Requires hypotenuse^2 = legA^2 + legB^2 
           *           (within the error tolerance of double arithmetic)
           */
          public RightTriangle(double legA, double legB, double hypotenuse) {
/*D*/         this.sides = new double[] { legA, legB };
/*D*/         this.hypotenuse = hypotenuse;
          }

          /** Get the two sides of the right triangle.
           *  @return two-element array with the triangle's side lengths
           */
          public double[] getAllSides() {
/*E*/         return sides;
          }

          /** @param factor to multiply the sides by
           *  @return a triangle made from this triangle by 
           *  multiplying all side lengths by factor.
           */
          public RightTriangle scale(double factor) {
              return new RightTriangle(sides[0]*factor, sides[1]*factor, hypotenuse*factor);
          }

          /** @return a regular triangle made from this triangle.
           *  A regular right triangle is one in which
           *  both legs have the same length.
           */
          public RightTriangle regularize() {
              double bigLeg = Math.max(side[0], side[1]);
              return new RightTriangle (bigLeg, bigLeg, hypotenuse);
          }

      }

  這裏說E處是有問題的代碼,即ide

public double[] getAllSides() {
/*E*/         return sides;
          }

  乍一看這裏返回了一個原來的引用,可能致使表示泄露。可是又一想,double是不可變類型啊!這裏即便改變了原來的double,可是return出去的double也不是原來那個double了,爲何會說代碼有問題呢?ui

  爲了證明個人判斷,我寫了下面的一段代碼:this

package hetest;

public class fianltest {
    private int ints;
    public int returnints()
    {
        return this.ints;
    }
    public fianltest (int ints) {
        this.ints=ints;
    }
    public static void main(String args[])
    {
        fianltest f=new fianltest(2);
        int g=f.returnints();
        g=g+1;
        System.out.println(f.returnints());
                
    }
}

  這段代碼運行結果是2,即沒有改變原來的int,那說明double確實也是不可變的,問題出在哪呢?spa

  這時我忽然想起來,這裏實際上返回的是double數組,那double數組是否是可變的呢?我打算本身驗證一下。因而有了下面的代碼:code

package hetest;

public class fianltest {
    private int [] ints;
    public int[] returnints()
    {
        return this.ints;
    }
    public fianltest (int[] ints) {
        this.ints=ints;
    }
    public static void main(String args[])
    {
        int [] i=new int[] {2};
        fianltest f=new fianltest(i);
        int[] g=f.returnints();
        g[0]=3;
        System.out.println(f.returnints()[0]);
        System.out.println(g[0]);        
    }
}

  這段代碼的運行結果是3,3.這也說明了,這裏對數組別名的更改影響到了內部表示,也就是說double數組是可變的!blog

相關文章
相關標籤/搜索