1.var与val:
使用val声明一个常量或值:val修饰的变量是不可变的,注意不可变的是引用,而不是内容,==val修饰的变量在编译后,等同于加上final==。
使用var 声明一个变量:var修饰的变量,内容和引用都可变
可变和不可变?
可变和不可变,指的是变量本身存的内容,值类型变量存的是数据本身,而引用类型变量存的是数据的引用,
值类型和引用类型?
值类型与引用类型区别:
存储方式:直接存储数据本身 vs 存储的是数据的引用,数据存储在数据堆中
内存分配:分配在栈中 vs 分配在堆中
效率:效率高,不需要地址转换 vs 效率较低,需要进行地址转换
内存回收: 使用完后立即回收 vs 使用完后不立即回收,而是交给GC处理回收
例如
lazy:只有val修饰的变量才能被lazy修饰,使用lazy定义变量后,==只有在调用该变量时才会实例化这个变量的值,并且只执行一次==,类似方法,先声明,后调用。
官方推荐val,使用val的好处:
- 更安全
- 代码可读性更高
- 资源回收更快,方法执行完,val所定义的变量即回收
2.val 与def
3.层级关系
# Any是所有类型的父类
它定义了一些通用的方法如equals、hashCode和toString。Any有两个直接子类:AnyVal和AnyRef。
# AnyVal是所有值类型的父类
有9个预定义的非空的值类型分别是:Double、Float、Long、Int、Short、Byte、Char、Unit和Boolean。Unit是不带任何意义的值类型,它仅有一个实例可以像这样声明:()。所有的函数必须有返回,所以说有时候Unit也是有用的返回类型。
# AnyRef是所有引用类型的父类
AnyRef代表引用类型。所有非值类型都被定义为引用类型。在Scala中,每个用户自定义的类型都是AnyRef的子类型。如果Scala被应用在Java的运行环境中,AnyRef相当于java.lang.Object。
# Nothing是所有类型的子类
Nothing是所有类型的子类,也是Null的子类,他没有一个具体的实例对象,常见的应用如:抛出异常、程序exit,无限循环等,返回值为Nothing类型。
Nothing没有对象,但是可以用来定义类型。例如,如果一个方法抛出异常,则异常的返回值类型就是Nothing(虽然不会返回) 。
def get(index:Int):Int = {
if(x < 0) throw new Exception(...) //返回值类型Nothing
else ....
}
# Null是所有引用类型的子类
Null只有一个实例对象null,主要用来和其他的JVM语言进行互操作,但是几乎不应该在Scala代码中使用。
4.运算符
object Operator {
def main(args: Array[String]): Unit = {
val (a, b) = (10, 7)
// 1. 算术运算符
println(s"a + b = ${a + b}")
println(s"a - b = ${a - b}")
println(s"a * b = ${a * b}")
println(s"a / b = ${a / b}")
println(s"a % b = ${a % b}")
// +:依然可以表示字符串的拼接运算符,类似于Java
// 2. 赋值运算符
var c = a + b
println(s"c = $c")
// 不同于Java,Scala的赋值运算是没有计算结果的
println(c = a + b)
// 3. 其他的运算符,和Java完全相同
// 4. 拓展:
println(a + b)
println(a.+(b)) // 相当于a调用了一个方法+, 参数就是b, 等价于 a + b
}
}
5、Scala中强制类型转换的方法
isInstanceOf[T]
asInstanceOf[T]