How are lazy val class variables implemented in Scala 2.10?

后端 未结 2 1967
名媛妹妹
名媛妹妹 2020-12-06 00:44

This answer to What\'s the (hidden) cost of Scala\'s lazy val? shows how they were implemented in Scala 2.7. But as the comments say, this must have changed since then, so I

2条回答
  •  遥遥无期
    2020-12-06 01:12

    Compiled this with scala 2.10.2:

    class Foo {
    
      lazy val bar = math.pow(5, 3)
    
    }
    

    Then decompiled the result with JD-GUI:

    import scala.math.package.;
    import scala.reflect.ScalaSignature;
    
    @ScalaSignature(bytes="\006\001e1A!\001\002\001\013\t\031ai\\8\013\003\r\tq\001P3naRLhh\001\001\024\005\0011\001CA\004\013\033\005A!\"A\005\002\013M\034\027\r\\1\n\005-A!AB!osJ+g\rC\003\016\001\021\005a\"\001\004=S:LGO\020\013\002\037A\021\001\003A\007\002\005!A!\003\001EC\002\023\0051#A\002cCJ,\022\001\006\t\003\017UI!A\006\005\003\r\021{WO\0317f\021!A\002\001#A!B\023!\022\001\0022be\002\002")
    public class Foo {
    
        private double bar;
        private volatile boolean bitmap$0;
    
        private double bar$lzycompute() {
            synchronized (this) { 
                if (!this.bitmap$0) { 
                    this.bar = package..MODULE$.pow(5.0D, 3.0D); 
                    this.bitmap$0 = true; 
                } 
                return this.bar; 
            }  
        } 
    
        public double bar() { 
            return this.bitmap$0 ? this.bar : bar$lzycompute(); 
        }
    
    }
    

    Edit - Here's what it looks like for three fields:

    class Foo {
    
      lazy val a = math.pow(5, 1)
      lazy val b = math.pow(5, 2)
      lazy val c = math.pow(5, 3)
    
    }
    

    Decompiled:

    import scala.math.package.;
    import scala.reflect.ScalaSignature;
    
    @ScalaSignature(bytes="\006\001\0052A!\001\002\001\013\t\031ai\\8\013\003\r\tq\001P3naRLhh\001\001\024\005\0011\001CA\004\013\033\005A!\"A\005\002\013M\034\027\r\\1\n\005-A!AB!osJ+g\rC\003\016\001\021\005a\"\001\004=S:LGO\020\013\002\037A\021\001\003A\007\002\005!A!\003\001EC\002\023\0051#A\001b+\005!\002CA\004\026\023\t1\002B\001\004E_V\024G.\032\005\t1\001A\t\021)Q\005)\005\021\021\r\t\005\t5\001A)\031!C\001'\005\t!\r\003\005\035\001!\005\t\025)\003\025\003\t\021\007\005\003\005\037\001!\025\r\021\"\001\024\003\005\031\007\002\003\021\001\021\003\005\013\025\002\013\002\005\r\004\003")
    public class Foo {
    
        private double a;
        private double b;
        private double c;
    
        private volatile byte bitmap$0;
    
        private double a$lzycompute() {
            synchronized (this) {
                if ((byte)(this.bitmap$0 & 0x1) == 0) {
                    this.a = package..MODULE$.pow(5.0D, 1.0D); 
                    this.bitmap$0 = ((byte)(this.bitmap$0 | 0x1)); 
                } 
                return this.a;
            }  
        } 
    
        private double b$lzycompute() { 
            synchronized (this) {
                if ((byte)(this.bitmap$0 & 0x2) == 0) {
                    this.b = package..MODULE$.pow(5.0D, 2.0D); 
                    this.bitmap$0 = ((byte)(this.bitmap$0 | 0x2)); 
                } 
                return this.b; 
            }  
        } 
    
        private double c$lzycompute() { 
            synchronized (this) {
                if ((byte)(this.bitmap$0 & 0x4) == 0) {
                    this.c = package..MODULE$.pow(5.0D, 3.0D); 
                    this.bitmap$0 = ((byte)(this.bitmap$0 | 0x4)); 
                } 
                return this.c;
            }
        }
    
        public double a() {
            return (byte)(this.bitmap$0 & 0x1) == 0 ? a$lzycompute() : this.a;
        }
    
        public double b() { 
            return (byte)(this.bitmap$0 & 0x2) == 0 ? b$lzycompute() : this.b; 
        } 
    
        public double c() { 
            return (byte)(this.bitmap$0 & 0x4) == 0 ? c$lzycompute() : this.c;
        }
    
    }
    

提交回复
热议问题