Gradle笔记1之Groovy基础语法

Gradle01

gradle概述

groovy和gradle

groovy是一种基于JVM的敏捷开发语言,它结合了Python,Ruby和Smalltalk的许多特性,同时它的代码可以和Java代码很好的结合,而且因为它能够运行在JVM上,因此Groovy能够直接使用其余的Java的jar包html

  • Groovy语言=Java语言的扩展+众多脚本语言的语法。运行在JVM虚拟机上
  • Gradle项目构框架使用groovy语言实现。基于Gradle框架为咱们实现了一些项目构件框架

开发环境搭建

groovy是须要运行在java虚拟机上的,因此须要安装java环境java

java环境

到java的官网下载jdk http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html程序员

而后解压下载好的压缩包,到硬盘中的任意位置web

而后配置环境变量,在终端中输入编程

subl ~/.zshrc

打开环境变量的配置,并添加java的配置vim

注: 我安装了 sublim text3,因此使用subl命令,若是没有,请使用vim命令,而且个人终端替换成了zsh,不然环境变量文件是.bash_profileapi

# JAVA
export JAVA_HOME=/home/chen/Programs/jdk1.8.0_171  
export JRE_HOME=${JAVA_HOME}/jre  
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib  
export PATH=${JAVA_HOME}/bin:$PATH

重启终端,在终端中输入ruby

java -version

看到显示java的相关信息了,则表示java环境变量配置成功bash

Groovy环境

配置Groovy环境的时候主要分红2步:
1. 下载Groovy
2. 解压并配置环境变量oracle

下载

打开groovy的下载页面,咱们会发现有不少版本,以目前来讲(2018.5.24)它提供了:
- Groovy2.6: Bleeding Edge Vesion
- Groovy2.5: upcoming version
- Groovy2.4: latest stable version

Bleeding Edge Vesion: 这个词不是很好翻译,它指的是那种最新的技术,可是须要承担必定的风险,而且使用者为了追求这种技术的新,也乐于承担这种风险的版本,而钢铁侠不是也有一套血边装甲嘛,好像用的也是bleeding edge这个词,不知道是否也有这种意思

图文无关

那么咱们选择下载2.4这个版本,它是最新的稳定版

选择下载这个SDK bundle,或者这个页面最上方大大下载按钮,对应的也是最新稳定版的下载连接:

在下载的时候要注意,groovy的版本和jdk的版本是须要对应的

这个indy和non-indy的意思是 需不须要支持Java的InvokeDynamic指令,这是java7中新增的一条字节码指令,若是咱们要使用的groovy使用这条指令进行编译的话那么至少须要1.7以上的java版本,而若是不使用该条指令的话,2.4其实也支持到1.6的jvm的,其实在咱们写groovy代码时影响不会很大,并且默认使用的也是groovy non-indy的版本,主要影响的是编译的过程,这里建议使用java8以上版本,毕竟java8也出了好长时间了,并且是最新的长期支持版本

解压并配置环境变量

下载好了以后,就能够解压到想要的地方了

解压

解压好了以后,和Java同样咱们须要配置环境变量:

subl ~/.zshrc
# groovy
export GROOVY_HOME=/home/chen/Programs/groovy-2.4.15
export PATH=${GROOVY_HOME}/bin:$PATH

其实就是把bin文件夹中配置进path中,配置完成后重启终端,而后输入:

groovy -v

看到

就表明咱们已经成功配置了groovy的环境变量

建立项目

我使用的idea进行建立groovy项目,idea的免费版也是支持groovy项目建立的,因此尚未使用idea的小伙伴能够尝试一波

在建立项目的时候,咱们注意要选择groovy就能够了,图中2的部分 若是idea没能正确识别你的groovy和java的安装路径的话,须要手动选一下,以后就一路next,正常的建立项目就能够了

基础语法

HelloWorld

建立好项目以后,咱们就能够来写groovy代码了,以前说过groovy是彻底兼容Java的,而兼容到什么程度呢,首先咱们先按Java代码的语法来写一个Groovy的HelloWorld

建立一个Groovy的类

咱们叫它HelloGroovy

class HelloGroovy {

    public static void main(String[] args) {
        System.out.println("Hello Groovy");
    }
}

运行一下:

能够看到咱们能够正常输出了,观察代码发现,这不就彻底是Java代码嘛,是的在Groovy中,你甚至能够写Java代码,那么groovy又在java代码的基础上能够简化成什么样子呢?

咱们知道,java要求咱们:
- 全部的代码必须写在一个类中
- 程序须要有一个主方法来运行
- 每一行语句都以分号结束

可是咱们的groovy就要灵活不少了,这些Java中的强制性要求,在groovy中都不存在,修改groovy代码以下:

System.out.println("Hello Groovy")

是的,就这一句,groovy是个脚本语言,它不须要类和方法,程序能够直接由上向下一行一行的执行,而且每一行的后面也不须要分号,咱们还能够简化这输出语句:

println "Hello Groovy"
println("Hello")

直接写println便可,而且在groovy中 容许在 顶级表达式中省略参数列表的小括号,就是你直接调用方法的参数,能够省略,要是方法的参数仍是一个方法,就不能省略小括号,例如:

println add(3, 4)
println(add(3, 4))

def add(a, b) {
    return a + b
}

这个add的小括号就不能省略,这个后面到方法的时候再说,总之能够发现使用groovy来写java代码,要比纯Java代码简洁不少,恩,语法其实有点相似与Python呢,而Groovy的代码,也须要编译,编译成的文件也是.class文件,这就是为何Groovy代码可以在JVM上运行,咱们直接用idea打开HelloGroovy.class文件,idea会自动把编译后的字节码给咱们反编译回来

import groovy.lang.Binding;
import groovy.lang.Script;
import org.codehaus.groovy.runtime.InvokerHelper;
import org.codehaus.groovy.runtime.callsite.CallSite;

public class HelloGroovy extends Script {
    public HelloGroovy() {
        CallSite[] var1 = $getCallSiteArray();
        super();
    }

    public HelloGroovy(Binding context) {
        CallSite[] var2 = $getCallSiteArray();
        super(context);
    }

    public static void main(String... args) {
        CallSite[] var1 = $getCallSiteArray();
        var1[0].call(InvokerHelper.class, HelloGroovy.class, args);
    }

    public Object run() {
        CallSite[] var1 = $getCallSiteArray();
        return var1[1].call(var1[2].callGetProperty(System.class), "Hello Groovy");
    }
}

能够看到全部咱们省略的东西,Groovy在编译成字节码的时候,编译器都给咱们自动加回来了~

变量

数据类型

在groovy中可使用全部Java的数据类型,咱们知道在Java中数据类型分为基本数据类型,和引用类型,而在groovy中则没有基本数据类型了,在groovy中,全部的基本数据类型都会在编译的时候转换成其包装类型:

int x = 10
println x
println x.class

能够看到咱们定义一个int类型的变量,在输出这个变量的类型的时候,发现它的类型是Integer,即它自动被转换成了引用类型

定义变量

咱们的Java是一门强类型语言,全部的变量的在定义的时候就须要声明好它的数据类型,例如:

public void fun(){
    // JAVA代码
    String name = "张三";
    int age = 18;
}

可是Groovy并非,它有类型推断机制,就好比咱们上面Java代码,到了groovy中,除了能够写成和Java如出一辙的之外,咱们还能够这样写:

def name = "张三"
def age = 18

println name
println age
println name.class
println age.class

运行结果

能够看到,不管是String类型,仍是int类型,咱们都使用的是def来进行定义变量的,而在输出他们的数据类型的时候,Groovy也知道name就是String类型,age就是Integer类型,这就是类型推断,由于咱们在定义变量的时候,直接为数据类型进行赋值了,那么编译器就会根据等号右面的值的数据类型,来决定等号左边变量的数据类型

类型推论、类型推断、或隐含类型,是指编程语言在编译期中可以自动推导出值的数据类型的能力,它是一些强静态类型语言的特性。通常而言,函数式编程语言也具备此特性。自动推断类型的能力让不少编程任务变得容易,让程序员能够忽略类型标注的同时仍然容许类型检查

其实Java中的类型推断机制也是逐步被增强的,例如在Java6中你须要这样定义一个String泛型的集合:

// java6
List<String> strings = new ArrayList<String>();

而到了Java7中咱们能够这样写:

// java7
List<String> strings = new ArrayList<>();

能够看到编译器已经愈来愈智能了,不须要咱们什么都写出来了,而java8中的lambda表达式也是这种类型推测机制更增强大的体现

那么什么时候定义变量的时候使用强类型定义,什么时候定义变量的时候使用def呢,总结下来有2点:
1. 若是变量只用于本身这个类而不会使用于其余模块,则使用def
2. 若是用于其余类的话 那么则使用强类型定义

其实不管是强类型定义仍是弱类型定义,都是为了咱们写程序更加的方便,易懂,那么若是咱们这个模块要给外部使用的时候,若是咱们也使用def的话,就会形成调用方的迷惑,不知道传给咱们什么类型的参数好了

动态类型

Java是一门静态类型的语言,即当数据的类型一旦肯定下来以后,就不可以在进行更改了,不然编译都过不去:

public class Main {
    public static void main(String[] args) {
        String s = "张三";
        s = 18;
    }
}

那么换到咱们的groovy中呢,咱们在定义变量的时候能够不指定类型,而去使用def,那么咱们能够写出以下代码:

def a = "张三"
println a.class
println a
a = 18
println a.class
println a
a = 3.14
println a.class
println a

能够看到在groovy中咱们就定义了一个a变量,而这个a变量能够根据运行时值的不一样,而动态的改变它的数据类型,咱们的Groovy是动态类型的语言,在写起来要比Java灵活不少,那么若是咱们使用传统的强类型定义方式去定义一个变量,变量的类型是否是就不能动态的改变了呢,看代码

String a = "张三"
println a.class
println a
a = 18
println a.class
println a

能够看到,强类型定义的方式,咱们的数据类型就被固定上了,不能再去改变了,而且若是两个数据类型没办法兼容的话,程序还会报错

int a = 3
a = '张三'

String类型

String类型是Java中很是经常使用的一种数据类型,甚至能够说是最经常使用的了,Groovy对Java中的String类型作了一些扩展,并把这些扩展封装进了GString(groovy.long.GString)中,就是说在Groovy中的字符串,对应两个类:String和GString,String类和Java中的String没有任何区别,主要看的是Groovy中特殊的GString

定义String

在Java中定义String是使用双引号:

String a = "Hello World";

可是在Groovy中就不仅只有这一种方法了,在Groovy中可使用单引号,双引号和三引号(三个单引号:”’)来定义一个String

def a = 'Hello'
def b = "Hello"
def c = '''Hello'''

println a.class
println b.class
println c.class

能够看到这三种方式均可以定义字符串,那么他们的区别是什么呢?

单引号

在groovy中使用单引号定义的字符串就是Java中最最普通的字符串,不能插值

双引号

在Groovy中若是双引号定义的字符串中没有插值表达式,那么双引号字符串就是普通的String类,若是有差值表达式的存在,则是GString的实例,插值表达式在下面会详细说明

三引号

三引号是多行字符串,使用起来和Python是同样的,能够直接在里面写换行,而不须要使用相似于\n这种的符号来表示换行

def s = '''锄禾日当午 汗滴禾下土 谁知盘中餐 粒粒皆辛苦 '''

println s

须要注意的是,这个字符串的每一次换行,其实都是给你自动的添加一个\n的

def s = '''锄禾日当午 汗滴禾下土 谁知盘中餐 粒粒皆辛苦 '''

println s.contains('\n')
println s.size()

能够看到字符串中是包含\n这个字符的,而且字符串的长度是24,20个字加上4个\n,那么若是我不想换行呢,可使用反斜杠来取消换行:

def s = '''\ 锄禾日当午,\ 汗滴禾下土 谁知盘中餐,\ 粒粒皆辛苦\ '''

println s

插值表达式

当使用双引号进行表示字符串时,咱们可使用字符串插值,就是用固定格式的字符串来进行占位,实际生成的时候,占位表达式会被动态的替换成响应的字符串

在groovy中使用${表达式}的形式来进行占位:

def youName = 'cfy'
def sayHello = "Hello: ${youName}"
println sayHello

插值表达式不光能够填写变量的值,还能够计算表达式的值,例如:

def sum = "sum=${5 + 3}"
println sum

字符串的使用

咱们知道在groovy中若是使用差值表达,那么它的数据类型就会变成GString,而咱们在使用的时候,实际上是不须要关心其数据类型的,String和GString之间是能够相互融合的:

def sum = "2 + 3 = ${2 + 3}"
def result = echo sum // 在使用时能够相互融合
println(result)
println(result.class)

String echo(String msg){
    return msg
}

咱们定义了一个方法,接受的参数是String类型的,而sum则是GString类型的,可是发现咱们的方法是能够正常调用的

String类的方法

在Groovy中,String类的方法能够有大支分为两类,一类是java.lang.String中的方法,另外一类是GString的方法,咱们主要看一下GString中的一些经常使用方法

def str = 'groovy'
// 把str使用-填充至18个字符,str在中间
println str.center(18,'-')
// 在原始字符串左边填充~至指定个个数
println str.padLeft(8, '~')
// 倒叙
println str.reverse()
// 首字母大写
println str.capitalize()
// 判断str是不是数字
println str.isNumber()
str = '89757'
println str.isNumber()
// 将字符串转换成整数类型
def a = str.toInteger()
println(a + ':' + a.class)

字符串运算

在groovy中扩展了字符串的比较:

def str = 'groovy'
def str2 = 'Hello'
println(str > str2) // true

两个字符串比大小,就是逐个比较每个字符的ascii的大小,在groovy,字符串还能够进行计算,+就是字符串的拼接,-则是在原始字符串中删除指定字符串,只会删除第一个;*就是原始字符串输出几回

str = 'hello'
str2 = str - 'l'
str3 = str * 3

println str2
println str3

子串

在groovy中取子串比较方便,可使用..操做符来表示范围

def str = 'groovy'
println str[0] // 取一个字符
println str[0..1] // 取范围
println str[-2..-1] // 从倒数第二个字符取到倒数第一个字符
println str[-1..0] // 从倒数第一个字符取到第0个字符,至关于倒叙输出