scala关键字val、var、def的区别
2018-01-23 16:07
656 查看
最近做项目时碰到scala一个很难理解的问题,一个接口里定义了某个方法,实现类里什么实现代码都没有,就是声明了一个同名的变量就可以直接运行了,真是莫名其妙(说实话不喜欢Scala,太多例外了)。案例代码如下:
接口A:
实现类B:
然后在B类中就可以直接使用接口A的dataMap方法了。明明都没有实现dataMap方法,怎么就可以直接使用这个方法了?
在回答上面的问题之前,先看下面的例子:
上面的测试类,使用val,var,def 并对他们不同位置进行了测试。我们使用 scalac Test.scala编译成Test.class,然后使用javap反编译查看具体实现:
反编译的代码如下:
从上面反编译的代码可以看出:
1)val是java的final不可变变量,var是java的普通变量;
2)在main函数里,val和var仅声明变量;
3)在class类定义里,val和var是先声明field存储空间,然后分别为他们定了同名的方法。
val 变量定义了 同名方法(类似于getter),来获取它的变量值;
var 变量定义了 同名方法(类似getter) 来获取它的变量值,同时提供了修改变量值的方法(类似于setter)
4)val/var和def的区别,可以从callByValue 和 callByName的角度来理解,val,var是callByValue, def是callByName.
callByValue 和callByName的区别,请移步:http://blog.csdn.net/qq_29343201/article/details/56281777
接口A:
trait A { def dataMap: Map[String, String] }
实现类B:
class B extends A { val dataMap = Map[String,String]() }
然后在B类中就可以直接使用接口A的dataMap方法了。明明都没有实现dataMap方法,怎么就可以直接使用这个方法了?
在回答上面的问题之前,先看下面的例子:
/** * Description: To Test the keyword of val,var,def. * * Author : Adore Chen * Created: 2018-01-23 */ class Test { val f1: Int = { println("val"); 1 } var f2: Int = { println("var"); 2} def f3: Int = { println("def"); 3} def main(args: Array[String]): Unit = { val f4: Int = 1 var f5: Int = 2 println(f4) } }
上面的测试类,使用val,var,def 并对他们不同位置进行了测试。我们使用 scalac Test.scala编译成Test.class,然后使用javap反编译查看具体实现:
javap -p -c Test
反编译的代码如下:
Compiled from "Test.scala" public class Test { private final int f1; private int f2; public int f1(); Code: 0: aload_0 1: getfield #14 // Field f1:I 4: ireturn public int f2(); Code: 0: aload_0 1: getfield #18 // Field f2:I 4: ireturn public void f2_$eq(int); Code: 0: aload_0 1: iload_1 2: putfield #18 // Field f2:I 5: return public int f3(); Code: 0: getstatic #28 // Field scala/Predef$.MODULE$:Lscala/Predef$; 3: ldc #30 // String def 5: invokevirtual #34 // Method scala/Predef$.println:(Ljava/lang/Object;)V 8: iconst_3 9: ireturn public void main(java.lang.String[]); Code: 0: iconst_1 1: istore_2 2: iconst_2 3: istore_3 4: getstatic #28 // Field scala/Predef$.MODULE$:Lscala/Predef$; 7: iload_2 8: invokestatic #43 // Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer; 11: invokevirtual #34 // Method scala/Predef$.println:(Ljava/lang/Object;)V 14: return public Test(); Code: 0: aload_0 1: invokespecial #50 // Method java/lang/Object."<init>":()V 4: aload_0 5: getstatic #28 // Field scala/Predef$.MODULE$:Lscala/Predef$; 8: ldc #52 // String val 10: invokevirtual #34 // Method scala/Predef$.println:(Ljava/lang/Object;)V 13: iconst_1 14: putfield #14 // Field f1:I 17: aload_0 18: getstatic #28 // Field scala/Predef$.MODULE$:Lscala/Predef$; 21: ldc #54 // String var 23: invokevirtual #34 // Method scala/Predef$.println:(Ljava/lang/Object;)V 26: iconst_2 27: putfield #18 // Field f2:I 30: return }
从上面反编译的代码可以看出:
1)val是java的final不可变变量,var是java的普通变量;
2)在main函数里,val和var仅声明变量;
3)在class类定义里,val和var是先声明field存储空间,然后分别为他们定了同名的方法。
val 变量定义了 同名方法(类似于getter),来获取它的变量值;
public int f1();
var 变量定义了 同名方法(类似getter) 来获取它的变量值,同时提供了修改变量值的方法(类似于setter)
public int f2();
public void f2_$eq(int);
4)val/var和def的区别,可以从callByValue 和 callByName的角度来理解,val,var是callByValue, def是callByName.
callByValue 和callByName的区别,请移步:http://blog.csdn.net/qq_29343201/article/details/56281777
相关文章推荐
- scala 中的def/val/lazy val/的区别,call-by-value/call-by-name
- scala 中的val 、 var 、def
- scala def/val/lazy val区别以及call-by-name和call-by-value
- Scala中的var val/def
- scala中val与def定义的区别
- Scala中的var val/def
- scala学习笔记-val和var的区别
- scala val 与var 区别
- scala val 和 var的区别
- Scala变量定义val与var的区别
- 2017.10.16 Scala中val和var的区别
- Scala中val和var的区别
- Scala中val和var的区别
- Scala 中的val 与 var 的区别 immutable 与 mutable 的 区别
- Kotlin的常量(val)和变量(var)的区别
- 简述C#中关键字var和dynamic的区别
- scala中的var 与 val
- Scala var && val
- Scala 的 val与var
- Kotlin: val和var的区别