zoukankan      html  css  js  c++  java
  • 软件构造复习中关于不变性的一个疑问以及代码验证

      在查看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处是有问题的代码,即

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

      乍一看这里返回了一个原来的引用,可能导致表示泄露。但是又一想,double是不可变类型啊!这里即使改变了原来的double,但是return出去的double也不是原来那个double了,为什么会说代码有问题呢?

      为了证实我的判断,我写了下面的一段代码:

    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确实也是不可变的,问题出在哪呢?

      这时我突然想起来,这里实际上返回的是double数组,那double数组是不是可变的呢?我打算自己验证一下。于是有了下面的代码:

    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数组是可变的!

      

  • 相关阅读:
    深入理解java虚拟机笔记Chapter12
    深入理解java虚拟机笔记Chapter11
    深入理解java虚拟机笔记Chapter8
    深入理解java虚拟机笔记Chapter7
    深入理解java虚拟机笔记补充-JVM常见参数设置
    深入理解java虚拟机笔记Chapter4
    深入理解java虚拟机笔记Chapter3-内存分配策略
    Java从Txt文本进行数据提取
    C语言-格式输入输出中“%d,%o,%x,%e,%f,%s,%p”
    嵌入式学习书籍
  • 原文地址:https://www.cnblogs.com/upuphe/p/13258640.html
Copyright © 2011-2022 走看看