企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
## **什么是变量?** [TOC] 变量就是**内容可以改变的量**。 在Kotlin中, 一切都是对象。所以,所有变量也都是对象(也就是说,任何变量都是根据引用类型来使用的)。 Kotlin的变量分为“**可变变量**”和“**不可变变量**”两种类型。 * **可变变量**通过**var**(来自variable)关键字进行声明, * **不可变变量**通过**val**(来自value)进行声明。 * 可变变量:变量可以进行多次修改,对应java中的普通变量(非final变量)。 * 不可变变量:变量只能进行一次初始化,对应java中的final类型的变量,一次赋值(只读)的变量。 * 本质上val也是变量,但一次赋值之后,不能再次修改,只能作为**只读变量**,val表示的是“常量”,但这并不是通俗意义上的常量。 >[success] **总结**: > 一、Kotlin相比于Java,不可变类型的变量只需要用val修饰即可,而不需要使用public static final修饰,是不是减少了一些代码呢? > 二、默认情况下,应该尽可能地使用val 关键字来声明所有的Kotlin变量,仅在必要的时候换成var 。使用不可变引用、不可变对象及无副作用的函数让你的代码更接近函数式编程风格。事实上在程序中大部分地方使用不可变的变量,可带来很多益处,如:可预测的行为和线程安全。 ### **var和val声明** 这里只是简单地一个举例,还有很多值得注意的地方 ~~~ //变量的声明和使用 fun main(args: Array<String>) {//固定写法,函数的入口 var name = "张三"// 计算机给我一个空间,空间的名字叫name,里面存放张三 // 这块空间存放的是字符串类型的数据 name = "李四"//这时候,name空间里面,李四代替张三,控制台输出也由张三变成李四 //如果此时执行以下代码 //name = 8//此时,就会报错,数字和字符串是不同的数据类型,8是一个数字 println(name) } ~~~ ### Kotlin在定义变量时与Java有以下几点不同 * [ ] 位置不同:在Kotlin中,数据类型要放到变量后面,并且用冒号隔开,这一点正好和Java想反 * [ ] 变量和常量需要关键字:在Kotlin中,定义变量需要用var开头,定义常量需要用val开头 * [ ] 数据类型首字母:在Kotlin中,数据类型都以大写字母开头,而在Java中,一般只有类、接口等复杂数据类型才会采用首字母大写的方式 * [ ] 如果在定义变量时未进行初始化,就必须指定数据类型,如果在定义变量时进行了初始化,就可以不指定数据类型,Kotlin编译器会自动根据等号右侧的值推导数据类型。 ### **注意** **①、如果一个变量只是声明,需要约束变量的具体类型**: ![](https://box.kancloud.cn/796924feef76b27d030bc3f28351cae9_529x236.jpg) 可以看到第7行代码,报错“This variable must either have a type annotation or be initialized”,即“这个变量要么有类型申明,要么被初始化”。因为**如果一个变量只申明不赋值,不约束变量具体类型是不允许的。** **②、Kotlin中变量不能重复定义**: ![](https://box.kancloud.cn/e3b8ef02cc335e860763420e549cb59a_522x239.jpg) 如图中所示,第5行和第7行,均报错“Conflicting declarations:var b:String ,var b:String",即变量b和变量b定义冲突 **③、变量声明有多种形式** 可以只声明变量不赋值变量,可以声明变量的同时赋值变量,可以声明变量和赋值变量分开。参考如下代码: ![](https://box.kancloud.cn/6bf5907f10c1caa405a3c3473e950a3b_615x298.jpg) **④、变量类型支持自动推断** 如果在声明变量的同时赋值了变量,那么我们可以省去变量类型,因为编译器有足够信息可以推断出变量的类型是什么,参考如下代码: ![](https://box.kancloud.cn/f13e0c6adc4ebf58a048c049a969e3ce_709x121.jpg) **⑤、不可变类型变量进行二次赋值会提示错误。** 如果变量类型是不可变类型,那么只能赋值一次,如果进行第二次赋值,则会提示错误,参考代码: ![](https://box.kancloud.cn/8b92f60f116b184aacba890db8cb6ab1_576x469.jpg) 从图中,看到num17行报错“Val cannot be reassigned”,也就是“Val类型变量,也就是不可变类型变量,不能被二次赋值”。 **⑥、val变量优先** val变量和var变量我们在开发过程中怎么去选择呢?只要可能,我们在开发中可以记住一个原则“**val类型变量优先**”,也就是我们**首先使用val不变值**。 **⑦、val类型变量和var类型变量字节码区别** 我们知道,val变量只能被赋值一次,那就类似Java语言中的final关键字修饰的变量。Kotlin中val关键字修饰的变量,是否会被转换成Java里面的final关键字修饰的变量呢?答案是:**val类型的成员变量a,转换为Java代码的时候,被添加上了final关键字**。 这里由于Eclipse,暂时无法查看Kotlin变量的字节码(或者鄙人孤陋寡闻,不知),当然也可以通过反编译的方式来查看字节码,具体为`javap -p A.class`,A是源文件生成的字节码文件的文件名。这里是引用网络上,使用**Idea**编辑Kotlin变量,查看字节码的GIF动图如下图所示: ![](https://i.loli.net/2019/04/18/5cb75bcfe01c6.gif) 查看大图,请[点击这里](https://i.loli.net/2019/04/18/5cb75bcfe01c6.gif) 下面摘抄自网络 怎么查看Kotlin代码编译之后的字节码文件呢?比如,我们想查看如下代码的字节码文件: ![](https://i.loli.net/2019/04/18/5cb75d3572b25.png) 双击两下Shift按键,调出“Search EveryWhere窗口”,然后输入“ShowBytecode” ![](https://i.loli.net/2019/04/18/5cb75d5ba4553.png) 点击进入,然后看到如下结果: ![](https://i.loli.net/2019/04/18/5cb75d8206951.png) 不过,字节码文件不通过单独的学习,我们没法看懂。我们可以把字节码文件转成java文件去看,接着我们点击“Decompile”按钮: ![](https://i.loli.net/2019/04/18/5cb75da256eb7.png) 看到如下结果,参考截图: ![](https://i.loli.net/2019/04/18/5cb75de27fb6a.png) 可以看到,val类型的成员变量a,转换为Java代码的时候,被添加上了final关键字。