Overview
本节介绍如何在四种语言中声明变量和常量。
Java 篇
变量
语法
数据类型 变量名 = 变量值;
例
String variable = "foo";
常量
在变量前加上关键字 final
就可以将变量声明为常量
例
final String constant = "foo";
Groovy 篇
变量
静态类型变量
声明方式与 Java 完全一致,但是 Groovy 不要求类型基本一致,只要等式右边的值能够向等式左边变量的类型进行转换那么变量的赋值仍旧成立
// 第二行报错,因为 10 无法转换为 Date 类型
Date date = new Date()
date = 10
// 正常运行,因为 Date 对象可以通过 toString() 方法转换为 String 类型
String str = "10"
str = new Date()
以上代码实际会被编译成如下的 Java 代码
Date date = (Date)ScriptBytecodeAdapter.castToType(var1[1].callConstructor(Date.class), Date.class);
String str = "10";
Object var6 = var1[2].callConstructor(Date.class);
str = (String)ShortTypeHandling.castToString(var6);
var1[3].callStatic(App.class, str);
可以看到第二个例子虽然在源代码层面上只使用变量 str
,但是在编译后实际使用了 str
, var6
两个变量。
动态类型变量
语法
def 变量名 = 变量值
例
def foo = "foo"
动态类型可以自由变换值和变量类型
常量
Groovy 定义常量的方式与 Java 相同,但是目前的 v2.4.x 版本还是存在历史遗留问题,常量实际上仍然可以被任意修改
例:
final String constant = "foo"
constant = 10
实际第二行的语句仍然可以正常执行
String constant = "foo";
以上是上述例子的编译结果,可以看到 final
关键字在编译后被完全丢弃了,目前这个 Bug 官方声称已经在 2.5.0-beta-1
版本修复了,具体情况可以查看 https://issues.apache.org/jira/browse/GROOVY-1628 和 https://issues.apache.org/jira/browse/GROOVY-2752 两个 issue。
Scala 篇
变量
语法
var 变量名: 变量类型 = 变量值
例
var variable: String = "foo"
常量(值)
在官方术语中, Scala 中的常量被实际被称为值
语法
val 值名: 值类型 = 具体值
例
val constant = "foo"
简便方式
在 Scala 中,无论是声明变量还是值时都可以直接省略类型说明
例
var variable = "foo"
val constant = "foo"
这种声明方式看起来像 Groovy 声明动态类型。但实际上 Scala 是比 Java 更强的静态类型语言,只是 Scala 更智能,如果你不明确指定类型的话,Scala 会通过等式右边的值来推断其数据类型,任何试图改变数据类型的行为都会报错。
Kotlin 篇
Kotlin 在使用时与 Scala 一致,这里就省略了。
Summary
- Groovy 声明方式类似 Java,但是支持声明动态类型;Scala 与 Kotlin 声明方法一样,都是将类型放在名称后面。
- 虽然四种语言都支持值不变的特性,但目前 Groovy 版本存在着 Bug
文章源码见 https://github.com/SidneyXu/JGSK 仓库的 _06_variable
小节