Gradle学习[2]——Groovy语言 JVM与Java是分离的,JVM要求输入class文件,Java编译后生成class文件让JVM执行,那么是不是可以自建其他语言然后按照JVM的要求编译成class文件让JVM执行呢?答案是可以的,Groovy就是这样,另外还有Kotlin。
Hello World Groovy语法可以简单理解成Java语法的简化(写得爽),下面给几个示例。
面向对象风格 Student类属性自带get、set:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Student { def name def age Student(name, age) { this .name = name this .age = age } Student() { } String toString(){ "name: $name, age: $age" } }
Main类:
1 2 3 4 5 6 7 8 9 10 11 12 static void main(String[] args) { println "Hello world!" def student = new Student() student['name' ] = "Tom" student.age = 19 println(student) } ------------------------------- Hello world!name: Tom, age: 19
面向过程风格 Groovy可以用面向函数的风格去写:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 class Man { def name def age Man(name, age) { this .name = name this .age = age } Man() { } String toString(){ "name: $name, age: $age" } } println("hello world" )def man = new Man() man.name = 'Tom' man.setAge(1 ) println mandef manList = [new Man("alis" ,18 ), new Man("Pic" , 21 )] println(manList)def pass = 'tom' def manMap = [A: new Man("Ast$pass" , 12 ), "B" :new Man("Bas$pass" , 23 )] println manMap --------------------------------------- hello worldname: Tom, age: 1 [name: alis, age: 18 , name: Pic, age: 21 ] [A: name: Asttom, age: 12 , B: name: Bastom, age: 23 ]
编译后实际上会生成与文件名相同的类去包裹代码,而定义的Man类会单独抽出来生成class。
开发者写得爽,少不了编译器在背后多干活。
语法规则总结 Groovy有着其他脚本语言便利的语法,如果不习惯这种风格,可以按着Java的方式写,它也可以引用Java的类库。上一张图总结一下大概的规则:
闭包 这个比较关键,它在Groovy构建脚本中无处不在。
它跟Java的lambda表达式有点点像,但它比lambda支持更多,表示闭包的为Closure对象。
下面举几个闭包的使用例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 { item++ } { -> item++ } { println it } { it -> println it } { name -> println name } { String x, int y -> println "hey ${x} the value is ${y}" } { reader -> def line = reader.readLine() line.trim() }def isOdd = { int i -> i%2 != 0 } assert isOdd(3 ) == true assert isOdd.call(2 ) == false def isEven = { it%2 == 0 } assert isEven(3 ) == false assert isEven.call(2 ) == true def run(Closure closure){ println("run start..." ) closure() println("run end..." ) } run { println "running......" }def caculate(Closure closure){ def num1=1 ; def num2=3 ; println("caculate start..." ) closure(num1,num2) println("caculate end..." ) } caculate {x,y -> println "计算结果为:$x+$y=${x+y}" }
PS 感觉Java可以比喻成爷爷,它是古板严肃的老一代。
Groovy比喻成孙子,它有着静态类型的特征也有动态类型的特征人很灵活但骨子里还是静态类型。
Java虽然也在不断加新特性,但是它没有抛下它的历史包袱,秉承着向下兼容的大旗就如同老狗学新花样,本质不变。
JDK10的支持var声明动态类型、JDK14的支持Record类型,还是JDK5泛型那套,靠编译器多干活。
隔壁的Python,从Python2到Python3就是个断崖式升级使得Python3不兼容Python2。