邓平凡Gradle教程的搬运工
文件名:Person.groovy
package bean
class Person {
String name
String gender
Person(name, gender) {
this.name = name
this.gender = gender
}
def print() {
println name + " " + gender
}
}
特点:直接可以运行(java需要在main()函数中执行)
文件名:run.groovy
功能:引用并创建了Person对象,调用他的方法
import bean.Person
def name = 'EvilsoulM'
def person=new Person(name,"male");
person.print()
Groovy文件都会编译成class文件运行在jvm上
猜想:脚本会不会编译成java类然后把代码都放到main函数中,
类似jsp脚本都会编译成类servlet然后运行在service方法中
就是这样的
Groovy把它转换成这样的Java类:
groovyc -d classes test.groovy
groovyc是groovy
的编译命令,-d classes用于将编译得到的class文件拷贝到classes文件夹下
jd-gui反编译它的代码:
定义成员变量
import groovy.transform.Field; //必须要先import
@Field x = 1 <==在x前面加上@Field标注,这样,x就彻彻底底是test的成员变量了。
文件名:ScriptBase.groovy
import groovy.transform.Field;
@Field author = 'EvilsouM'
@Field gender = 'male'
@Field age = 25
//必须要先import
def printInfo() {
println "name->$author gender->$gender age->$age"
}
文件名:ScriptBase.groovy
class ScriptBase {
def author = 'EvilsouM'
def gender = 'male'
def age = 25
def printInfo() {
println "name->$author gender->$gender age->$age"
}
}
def Closure printAuthorInfo = {
String name, String gender, int age ->
println "name->$name gender->$gender age->$age"
}
def ScriptBase base = new ScriptBase()
base.printInfo()
printAuthorInfo.call(base.author, base.gender, base.age) 上面两种方式都能拿到成员变量
所有表达式或者声明都不用加分号结尾
def var =1
def str= "i am a person"
def int x = 1//也可以指定类型
def nonReturnTypeFunc(){
last_line //最后一行代码的执行结果就是本函数的返回值
}
//如果指定了函数返回类型,则可不必加def关键字来定义函数
String getString(){
return "I am a string"
}
函数调用可以不加括号,这和属性的引用容易混淆
函数名称+( )/(参数值)
函数名称 参数值
三种写法:
- ‘string’
- “string”
- ”’string”’
区别:
Groovy对字符串支持相当强大,充分吸收了一些脚本语言的优点:
1 单引号”中的内容严格对应Java中的String,不对$符号进行转义
def singleQuote='I am $ dolloar' //输出就是I am $ dolloar
2 双引号”“的内容则和脚本语言的处理有点像,如果字符中有 号的话,则它会 表达式先求值。
def doubleQuoteWithoutDollar = "I am one dollar" //输出 I am one dollar
def x = 1
def doubleQuoteWithDollar = "I am $x dolloar" //输出I am 1 dolloar
3 三个引号”’xxx”’中的字符串支持随意换行 比如
def multieLines = ''' begin
line 1
line 2
end '''
作为动态语言,Groovy世界中的所有事物都是对象。所以,int,boolean这些Java中的基本数据类型,在Groovy代码中其实对应的是它们的包装数据类型。比如int对应为Integer,boolean对应为Boolean
基本用法参考:http://www.groovy-lang.org/api.html
变量定义:List变量由[]定义,比如
def aList = [5,'string',true] //List由[]定义,其元素可以是任何对象
变量存取:可以直接通过索引存取,而且不用担心索引越界。如果索引超过当前链表长度,List会自动
往该索引添加元素
assert aList[1] == 'string'
assert aList[5] == null //第6个元素为空
aList[100] = 100 //设置第101个元素的值为10
assert aList[100] == 100
那么,aList到现在为止有多少个元素呢?
println aList.size ===>结果是101
变量定义:Map变量由[:]定义,比如
def aMap = ['key1':'value1','key2':true]
Map由[:]定义,注意其中的冒号。冒号左边是key,右边是Value。key必须是字符串,value可以是任何对象。另外,key可以用''或""包起来,也可以不用引号包起来。比如
def aNewMap = [key1:"value",key2:true] //其中的key1和key2默认被
处理成字符串"key1"和"key2"
不过Key要是不使用引号包起来的话,也会带来一定混淆,比如
def key1="wowo"
def aConfusedMap=[key1:"who am i?"]
aConfuseMap中的key1到底是"key1"还是变量key1的值“wowo”?显然,答案是字符串"key1"。如果要是"wowo"的话,则aConfusedMap的定义必须设置成:
def aConfusedMap=[(key1):"who am i?"]
Map中元素的存取更加方便,它支持多种方法:
println aMap.keyName <==这种表达方法好像key就是aMap的一个成员变量一样
println aMap['keyName'] <==这种表达方法更传统一点
aMap.anotherkey = "i am map" <==为map添加新元素
def aRange = 1..5 <==Range类型的变量 由begin值+两个点+end值表示
左边这个aRange包含1,2,3,4,5这5个值
如果不想包含最后一个元素,则
def aRangeWithoutEnd = 1..<5 <==包含1,2,3,4这4个元素
println aRange.from
println aRange.to
JavaScript中闭包是一个函数
Groovy中闭包是一种数据类型:Closure
定义形式
def xxx = {paramters -> code} //或者
def xxx = {无参数,纯code} 这种case不需要->符号
def aClosure = {//闭包是一段代码,所以需要用花括号括起来..
String param1, int param2 -> //这个箭头很关键。箭头前面是参数定义,箭头后面是代码
println"this is code" //这是代码,最后一句是返回值,
//也可以使用return,和Groovy中普通函数一样
}
和定义函数的区别:
闭包的使用
和函数调用差不多
可以是用call方法
Closure.call("this is string",100)
aClosure("this is string", 100)
闭包作为函数参数
def iamList = [1,2,3,4,5] //定义一个List
iamList.each{ //调用它的each,这段代码的格式看不懂了吧?each是个函数,圆括号去哪了?
println it//默认参数为it
}
参考API:http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/File.html
1 读该文件中的每一行:eachLine的唯一参数是一个Closure。Closure的参数是文件每一行的内容
其内部实现肯定是Groovy打开这个文件,然后读取文件的一行,然后调用Closure…
def File targetFile = new File("build.gradle")
targetFile.eachLine {
String line ->
println line
}
2 直接得到文件内容
targetFile.getBytes() <==文件内容一次性读出,返回类型为byte[]
3 使用InputStream.InputStream的SDK在 http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/InputStream.html
def ism = targetFile.newInputStream()
//操作ism,最后记得关掉
ism.close
4 使用闭包操作inputStream,以后在Gradle里会常看到这种搞法
targetFile.withInputStream{
ism -> 操作ism. 不用close。Groovy会自动替你close
}
和读文件差不多。不再啰嗦。这里给个例子,告诉大家如何copy文件。
def srcFile = new File(源文件名)
def targetFile = new File(目标文件名)
targetFile.withOutputStream{
os-> srcFile.withInputStream {
ins->
os << ins //利用OutputStream的<<操作符重载,完成从inputstream到OutputStream //的输出
}
}