int[] array = { 1, 2, 3}
在大二下学期的时候 有幸接触到android开发 那时候我们选用的ide是android studio。其中它的构建工具gradle引起了我们的注意 据说超过ant 和 maven 。比如maven,maven 是通过xml进行描述的 虽然xml十分易读 但是它却很难表示 if else 这样的语句
第一篇博文从groovy开始 gradle选择用groovy来描述 groovy 基于java 并且扩展了java 它使得代码写的像脚本语言一样 然后就可以编译执行 不过在执行的时候 它会变成java class 然后由jvm运行
流程图
首先我们开始学习如何安装
登录官网 http://www.groovy-lang.org/download.html#gvm 点击打开链接
如果你不嫌弃 我可以帮忙翻译 (我的os 是ubuntu jdk 1.8)
大致如下几步:
这时候你可以尝试 运行 groovy -version
如果没有这个命令
先cd .gvm
然后ls 一下就看到了 到最后的bin 目录
用 gedit 编辑一个文件 以groovy结尾
内容为
println "hello world"
便有我上面的运行效果
OK 那我们开始正式的学习
首先 groovy设计时有意让java程序员快速的适应 也就是说它某些地方还是和java不同的 所以我们依次来学习
# 导包 在java 里面需要用import 关键字而在groovy中
只需
# 函数重载匹配方案不同
在java里面 重载函数时 编译器在编译时确定最匹配的函数 这是根据类型来确定的 不同的是groovy是在运行时进行匹配 所以在java里面 上述函数返回2 而在groovy中是1
# 数组初始化
In Groovy, the { … }
block is reserved for closures. That means that you cannot create array literals with thissyntax:
在groovy中 { }中的区域是用于闭包的 也就是说你不能像java一样初始化如下的数组
int[] array = { 1, 2, 3}
You actually have to use:
你应该这样使用 (这个是groovy中的数据结构后面会讲到)
int[] array = [1,2,3]
# 包范围的访问权限不同(package scope visibility)
class Person {
String name
}
当缺少权限修饰符的时候 这里不会创建一个包私有的权限
相反的 它创建了一个私有的属性 并且这个属性由setter 和 getter
如果你要创建一个包私有的权限 那么是要用注释来完成
一如
class Person {
@PackageScope String name
}
# ARM blocks
ARM(自动资源管理)块groovy是不支持的
一如如下的代码
Path file = Paths.get("/path/to/file");
Charset charset = Charset.forName("UTF-8");
try (BufferedReader reader = Files.newBufferedReader(file, charset)) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
相反的 groovy使用闭包来完成这个功能
new File('/path/to/file').eachLine('UTF-8') {
println it
}
or, if you want a version closer to Java:
new File('/path/to/file').withReader('UTF-8') { reader ->
reader.eachLine {
println it
}
}
# 内部类
在groovy中 匿名内部类 和 嵌套类是和java中语法一样的 实现方式和闭包一样 这带来一些好处和坏处。比如我们访问私有域和方法已经不可能 不过我们这样就不必将本地变量变成final啦
# 静态内部类
举个例子
class A {
static class B {}
}
new A.B()
Anonymous Inner Classes
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
CountDownLatch called = new CountDownLatch(1)
Timer timer = new Timer()
timer.schedule(new TimerTask() {
void run() {
called.countDown()
}
}, 0)
assert called.await(10, TimeUnit.SECONDS)
# 创建非静态内部类时 groovy和java不同
一如在java中:
public class Y {
public class X {}
public X foo() {
return new X();
}
public static X createX(Y y) {
return y.new X();
}
}
public class Y {
public class X {}
public X foo() {
return new X()
}
public static X createX(Y y) {
return new X(y)
}
}
我们直接new X(y)就行
值得注意的是 在groovy中 如果一个函数 它只有一个参数 那么我们在调用它的时候 可以不传入一个参数 那么那个参数将是null的
同样的原理适用于ctor 当你写new X() 而不是 new X(this)的时候 这是非常危险的 到目前位置还没有好的方法解决这个问题:(
# lambda
在java 8里面支持lambda 和方法引用 一如:
Runnable run = () -> System.out.println("Run");
list.forEach(System.out::println);
在groovy中不支持那样的语法 但是我们可以用闭包来实现
Runnable run = { println 'run' }
list.each { println it } // or list.each(this.&println)
As double-quoted string literals are interpreted as GString
values, Groovy may failwith compile error or produce subtly different code if a class withString
literalcontaining a dollar character is compiled with Groovy and Java compiler.
While typically, Groovy will auto-cast between GString
and String
if an API declaresthe type of a parameter, beware of Java APIs that accept anObject
parameter and thencheck the actual type.
典型的,groovy将会自动转换GString 和String
# String 和 字符 字面值
Singly-quoted literals in Groovy are used for String
, and double-quoted result inString
orGString
, depending whether there is interpolation in the literal.
在groovy中 单引号是用作String ,而双引号可以用于String 和 GString,这具体还是要取决于字面值中是否有interpolation(我觉得可以译为 插值)
println 'c'.getClass()==String
println "c".getClass()==String
println "c${1}".getClass() in GString
当一个String赋值给一个char变量时,groovy将自动转换只有单字符的String到char中。
当调用一个方法 并且这个方法的参数是一个char时 我们需要显示的转换 否则你就要确定一切都在预想中进行
Groovy supports two styles of casting and in the case of casting to char
thereare subtle differences when casting a multi-char strings. The Groovy style cast ismore lenient and will take the first character, while the C-style cast will failwith exception.
groovy支持两种风格的格式转换 并且 转换一个字符和转换一个多字符的字符串有一些微妙的区别。
groovy的转换更宽容 并且只会获取第一个字符 而c风格的转换将会导致一个异常的抛出
# == 符号的行为差别
In Java ==
means equality of primitive types or identity for objects. InGroovy==
translates to a.compareTo(b)==0
, iff they are Comparable
, anda.equals(b)
otherwise. To check for identity, there isis
. E.g.a.is(b)
.
在java中== 只是比较引用是否相同 而在groovy中如果a b是可比的 == 将被转换成a.compareto(b) == 0 ,或者a.equals(b) 为了检查 引用是否都指向同一地址 可以使用a.is(b)
# 关键字不同
java中的关键字是groovy的子集
groovy中还包括