groovy_groovy 定义list - CSDN
groovy 订阅
Groovy是一种基于JVM(Java虚拟机)的敏捷开发语言,它结合了Python、Ruby和Smalltalk的许多强大的特性,Groovy 代码能够与 Java 代码很好地结合,也能用于扩展现有代码。由于其运行在 JVM 上的特性,Groovy也可以使用其他非Java语言编写的库。 展开全文
Groovy是一种基于JVM(Java虚拟机)的敏捷开发语言,它结合了Python、Ruby和Smalltalk的许多强大的特性,Groovy 代码能够与 Java 代码很好地结合,也能用于扩展现有代码。由于其运行在 JVM 上的特性,Groovy也可以使用其他非Java语言编写的库。
信息
类    别
编程语言
发行时间
2003年
外文名
Groovy
创作者
Guillaume Laforge
Groovy简介
Groovy 是 用于Java虚拟机的一种敏捷的动态语言,它是一种成熟的面向对象编程语言,既可以用于面向对象编程,又可以用作纯粹的脚本语言。使用该种语言不必编写过多的代码,同时又具有闭包和动态语言中的其他特性。Groovy是JVM的一个替代语言(替代是指可以用 Groovy 在Java平台上进行 Java 编程),使用方式基本与使用 Java代码的方式相同,该语言特别适合与Spring的动态语言支持一起使用,设计时充分考虑了Java集成,这使 Groovy 与 Java 代码的互操作很容易。(注意:不是指Groovy替代java,而是指Groovy和java很好的结合编程。 [1]  (概述图片来源:)
收起全文
精华内容
参与话题
  • Groovy精简教程

    千人学习 2018-10-22 21:38:03
    注重实践,剔除繁琐的理论,通过案例讲解我们常用的知识点,各个知识点之间相对独立,不用担心某一个知识点学不会而耽搁学其他的知识点。轻轻松松入门Groovy
  • Groovy入门(一)—— Groovy语法

    万次阅读 2017-10-14 14:42:07
    Groovy语法 1. 注释 1.1. 单行注释 Groovy单行注释以//开头,可以出现在程序的各个位置。 // a standalone single line comment println "hello" // a comment till the end of the line 1.2. 多行注释 多行...

    Groovy语法

    1. 注释

    1.1. 单行注释

    Groovy单行注释以//开头,可以出现在程序的各个位置。

    // a standalone single line comment
    println "hello" // a comment till the end of the line

    1.2. 多行注释

    多行注释以 /* 开头,以 */ 结尾,可以出现在程序的任何位置。

    /* a standalone multiline comment
       spanning two lines */
    println "hello" /* a multiline comment starting
                       at the end of a statement */
    println 1 /* one */ + 2 /* two */

    1.3. GroovyDoc

    GroovyDoc以 /** 开头,以 */结尾,中间行一般可以选择性的以 * 开头。

    GroovyDoc一般用于:

    • 类型定义 (classes, interfaces, enums, annotations)
    • 字段或属性定义
    • 方法定义
    /**
     * A Class description
     */
    class Person {
        /** the name of the person */
        String name
        /**
         * Creates a greeting method for a certain person.
         *
         * @param otherPerson the person to greet
         * @return a greeting message
         */
        String greet(String otherPerson) {
           "Hello ${otherPerson}"
        }
    }

    1.4. Shebang line

    #开头写在文件的第一行,告诉Unix或类Unix系统以何种解释器去运行脚本。前提是已经安装了Groovy,并且配置完PATH。

    #!/usr/bin/env groovy
    println "Hello from the shebang line"

    2. 关键字

    as assert break case catch class const continue def default do else enum extends false finally for goto if implements import in instanceof interfacenew null package return super switch this throwthrows trait true try while

    3. 标识符

    3.1. 普通标识符(Normal identifiers)

    标识符以字母、$、_开头,不能以数字开头,但后面可以跟数字。

    字母的的取值区间为:

    • 'a' to 'z' (lowercase ascii letter)
    • 'A' to 'Z' (uppercase ascii letter)
    • '\u00C0' to '\u00D6'
    • '\u00D8' to '\u00F6'
    • '\u00F8' to '\u00FF'
    • '\u0100' to '\uFFFE'

    eg:

    def name
    def item3
    def with_underscore
    def $dollarStart

    3.2. 引用标识符(Quoted identifiers)

    引用标识符是.(dot)后的表达式。比如说nameperson.name的一部分,那么我们可以通过person."name"或者person.'name'来引用它。这点与Java不同,Java不允许这种格式的引用。eg:

    def map = [:]
    
    map."an identifier with a space and double quotes" = "ALLOWED"
    map.'with-dash-signs-and-single-quotes' = "ALLOWED"
    
    assert map."an identifier with a space and double quotes" == "ALLOWED"
    assert map.'with-dash-signs-and-single-quotes' == "ALLOWED"

    Groovy提供了不同种类的字符串字面量,所有String类型的字面量都允许写到.后作为引用标识符。eg:

    map.'single quote'
    map."double quote"
    map.'''triple single quote'''
    map."""triple double quote"""
    map./slashy string/
    map.$/dollar slashy string/$

    4. String

    Groovy支持java.lang.String和GString(groovy.lang.GString)字符串类型,其中GString在一些编程语言中被称作interpolated stringsWikipedia - String interpolation

    4.1. 单引号字符串(Single quoted string)

    单引号字符串被解释成java.lang.string,不支持内插值。

    'a single quoted string'

    4.2. 字符串拼接

    Groovy中连接字符串使用+

    assert 'ab' == 'a' + 'b'

    4.3. 三单引号字符串(Triple single quoted string)

    三单引号字符串被解释成java.lang.String类型,不支持内插值。

    三单引号支持多行,支持文本跨行,并且不需要换行符,字符串原样输出。eg:

    def aMultilineString = '''line one
    line two
    line three'''

    通常,代码在格式化完毕之后,会保持缩进。对于三单引号字符串来说,会把缩进也原样输出。Groovy提供了String#stripIndent()方法来去掉字符串前的缩进,并且提供了String#stripMargin()方法,可以删除字符串开始位置的指定分隔符。

    当我们创建如下的字符串时:

    def startingAndEndingWithANewline = '''
    line one
    line two
    line three
    '''

    会发现字符串开头包含一个换行符\n,可以通过字符串开头添加``来消除开头的换行符。

    def strippedFirstNewline = '''\
    line one
    line two
    line three
    '''
    assert !strippedFirstNewline.startsWith('\n')

    4.4. 双引号字符串

    "a double quoted string"

    当双引号字符串中没有插值表达式时,字符串的类型为java.lang.String,当双引号字符串中包含插值表达式时,字符串类型为groovy.lang.GString

    4.4.1 字符串插值(String interpolation)

    除了单引号字符串和三单引号字符串以外,任何Groovy表达式可以出现在所有的字符串字面量中。插值实际上是替换字符串中的占位符。占位符表达式是被${}围绕或以$为前缀的点表达式(dotted expressions),当GString传递给一个以String类型作为参数的方法时,会调用toString方法,将占位符替换为表达式所代表的值。eg:

    def name = 'Guillaume' // a plain string
    def greeting = "Hello ${name}"
    assert greeting.toString() == 'Hello Guillaume'
    def sum = "The sum of 2 and 3 equals ${2 + 3}"
    assert sum.toString() == 'The sum of 2 and 3 equals 5'

    实际上${}中不仅可以使用表达式,也可以写声明语句,但是这些语句的返回值为null,例如"The sum of 1 and 2 is equal to ${def a = 1; def b = 2; a + b}"在Groovy中是被支持的,但是一般在Groovy中不推荐这样写。更好的写法是在GString中只使用简单的占位符。

    使用$点表达式(dotted expressions),eg:

    def person = [name: 'Guillaume', age: 36]
    assert "$person.name is $person.age years old" == 'Guillaume is 36 years old'

    使用$点表达式(dotted expressions)的时候,只允许a.ba.b.c的写法,不能调用方法,否则会抛出groovy.lang.MissingPropertyException的异常。因为Groovy在替换插值时调用的是toString方法。

    def number = 3.14
    
    shouldFail(MissingPropertyException) {
        println "$number.toString()" // groovy.lang.MissingPropertyException
    }

    "$number.toString()" 替换为 "${number.toString}()" 可以正常运行。

    4.4.2. 特殊的插值闭包表达式(Special case of interpolating closure expressions)

    闭包表达式的格式为:${->},简单的理解为一个闭包前面加了一个$符号。eg:

    def sParameterLessClosure = "1 + 2 == ${-> 3}" 
    assert sParameterLessClosure == '1 + 2 == 3'
    
    def sOneParamClosure = "1 + 2 == ${ w -> w << 3}" 
    assert sOneParamClosure == '1 + 2 == 3'

    关于闭包表达式:

    • 闭包是无参的
    • 闭包包含一个java.io.StringWriter参数,可以通过追加内容到>>后面的方式添加。

    闭包表达式只能有0个或1个参数。

    闭包表达式和普通表达式唯一的不同是:lazy evaluation 。详情移步 —> Wikipedia - Lazy evaluation

    def number = 1 
    def eagerGString = "value == ${number}"
    def lazyGString = "value == ${ -> number }"
    
    assert eagerGString == "value == 1" 
    assert lazyGString == "value == 1" 
    
    number = 2 
    assert eagerGString == "value == 1" // eagerGString不会再次求值
    assert lazyGString == "value == 2"  // lazyGString会再次求值
    4.4.3. GString and String hashCodes

    尽管GString可以代替String,但是他们还一处不同:他们的hashCodes不同。原生的Java String 是immutable(不可变的),但是GString所表示的String却是可变的,依赖于的它的插值。即使GString和Java原生String类型有相同的字面量,它们的hashCodes的值可能不同。eg:

    assert "one: ${1}".hashCode() != "one: 1".hashCode()

    由于GString和String的hashCodes不同,所以应该避免使用使用GString作为Map的key。eg:

    def key = "a"
    def m = ["${key}": "letter ${key}"]     
    assert m["a"] == null

    4.5. 三双引号字符串( Triple double quoted string)

    类似于三单引号字符串,支持跨行。也类似双引号字符,支持GString插值操作。

    def name = 'Groovy'
    def template = """
        Dear Mr ${name},
        You're the winner of the lottery!
        Yours sincerly,
        Dave
    """
    
    assert template.toString().contains('Groovy')

    4.6. Slashy string

    /作为界定符的字符串,叫做Slashy string。它通常被用于写正则表达式,因为不需要转译的反斜线``。

    def fooPattern = /.*foo.*/
    assert fooPattern == '.*foo.*'

    如果字符串中间出现/,这种情况下才需要转译。eg:

    def escapeSlash = /The character \/ is a forward slash/
    assert escapeSlash == 'The character / is a forward slash'

    Slashy string允许跨行,eg:

    def multilineSlashy = /one
        two
        three/
    
    assert multilineSlashy.contains('\n')

    Slashy string支持插值操作,类似GString。eg:

    def color = 'blue'
    def interpolatedSlashy = /a ${color} car/
    
    assert interpolatedSlashy == 'a blue car'

    如果Slashy string是空字符串//,那么编译过程中会把//当做注释。

    4.7. Dollar slashy string

    Dollar slashy string相当于跨行的GString,以$/开头,以/$结尾。以$作为转译字符,可以转译另一个$/

    4.8. 字符(Characters)

    Groovy没有明确的字符类型,可以通过以下三种方式创建:

    char c1 = 'A'  // 类型声明为char
    assert c1 instanceof Character 
    
    def c2 = 'B' as char  // 通过as将类型强制指定为char
    assert c2 instanceof Character
    
    def c3 = (char)'C'  // 通过类型转换
    assert c3 instanceof Character

    5. 数值(Numbers)

    5.1. 整型(Integral literals)

    Groovy的整型和Java类似:

    • byte
    • char
    • short
    • int
    • long
    • java.lang.BigInteger

    eg:

    // primitive types 原始类型
    byte b = 1
    char c = 2
    short s = 3
    int i = 4
    long l = 5
    
    // infinite precision 引用类型
    BigInteger bi = 6

    如果使用def声明类型,那么这个整型是可变的。它会数值的大小来匹配类型。(负数也如此)

    def a = 1
    assert a instanceof Integer
    
    // Integer.MAX_VALUE
    def b = 2147483647
    assert b instanceof Integer
    
    // Integer.MAX_VALUE + 1
    def c = 2147483648
    assert c instanceof Long
    
    // Long.MAX_VALUE
    def d = 9223372036854775807
    assert d instanceof Long
    
    // Long.MAX_VALUE + 1
    def e = 9223372036854775808
    assert e instanceof BigInteger

    其它进制:

    • 2进制是以0b开头的数字
    • 8进制是以0开头的数字
    • 16进制是以0x开头的数字

    5.2. 浮点数(Decimal literals)

    浮点数类型和Java类似:

    • float
    • double
    • java.lang.BigDecimal

    浮点数类型支持指数,通过eE实现。

    // primitive types
    float f = 1.234
    double d = 2.345
    
    // infinite precision
    BigDecimal bd = 3.456
    
    assert 1e3 == 1_000.0
    assert 2E4 == 20_000.0
    assert 3e+1 == 30.0
    assert 4E-2 == 0.04
    assert 5e-1 == 0.5

    为了计算的准确性,Groovy使用BigDecimal作为浮点数的默认类型。除非显示的声明floatdouble,否则浮点数类型为java.lang.BigDecimal。尽管如此,在一些接受参数为floatdouble的方法中,依然可以使用BigDecimal类型作为参数传递。

    5.3. 数值中使用下划线

    当数值过长的时候,可以使用_对数字进行分组,以使阅读更加简洁明了。eg:

    long creditCardNumber = 1234_5678_9012_3456L
    long socialSecurityNumbers = 999_99_9999L
    double monetaryAmount = 12_345_132.12
    long hexBytes = 0xFF_EC_DE_5E
    long hexWords = 0xFFEC_DE5E
    long maxLong = 0x7fff_ffff_ffff_ffffL
    long alsoMaxLong = 9_223_372_036_854_775_807L
    long bytes = 0b11010010_01101001_10010100_10010010

    5.4. 数值类型后缀(Number type suffixes)

    可以通过使用后缀来指定数字类型

    • BigInteger类型后缀为Gg
    • Long类型后缀为Ll
    • Integer类型后缀为Ii
    • Bigdecimal类型后缀为Gg
    • Double类型后缀为Dd
    • Float类型后缀为Ff

    eg:

    assert 42I == new Integer('42')
    assert 42i == new Integer('42') // lowercase i more readable
    assert 123L == new Long("123") // uppercase L more readable
    assert 2147483648 == new Long('2147483648') // Long type used, value too large for an Integer
    assert 456G == new BigInteger('456')
    assert 456g == new BigInteger('456')
    assert 123.45 == new BigDecimal('123.45') // default BigDecimal type used
    assert 1.200065D == new Double('1.200065')
    assert 1.234F == new Float('1.234')
    assert 1.23E23D == new Double('1.23E23')
    assert 0b1111L.class == Long // binary
    assert 0xFFi.class == Integer // hexadecimal
    assert 034G.class == BigInteger // octal

    6. Boolean

    布尔类型是一种特殊的类型用于判断对或错:truefalse。Groovy有一套特别的规则用于强制将non-boolean类型转换为bollean类型。

    7. List

    Groovy中没有定义自己的List类型,使用的是java.util.List类型。通过一对[]包括,里面的元素以,分隔来定义一个List。默认情况下,创建的List的类型为java.util.ArrayList。eg:

    def numbers = [1, 2, 3]         
    
    assert numbers instanceof List  
    assert numbers.size() == 3

    List中元素可以是不同类型:

    def heterogeneous = [1, "a", true]

    通过使用as操作符可以强制指定List的类型,或者在声明List变量时强制指定类型。eg:

    def arrayList = [1, 2, 3]
    assert arrayList instanceof java.util.ArrayList
    
    def linkedList = [2, 3, 4] as LinkedList    
    assert linkedList instanceof java.util.LinkedList
    
    LinkedList otherLinked = [3, 4, 5]          
    assert otherLinked instanceof java.util.LinkedList

    可以使用[]获取List中的元素,可以使用<<向list末尾追加元素。

    def letters = ['a', 'b', 'c', 'd']
    assert letters[0] == 'a'     
    assert letters[1] == 'b'
    assert letters[-1] == 'd'    
    assert letters[-2] == 'c'
    letters[2] = 'C'             
    assert letters[2] == 'C'
    letters << 'e'               
    assert letters[ 4] == 'e'
    assert letters[-1] == 'e'
    assert letters[1, 3] == ['b', 'd']         
    assert letters[2..4] == ['C', 'd', 'e']

    8. Arrays

    Groovy定义数组的方式和定义list的方式一样,只不过声明时需要制定类型,或者通过as来强制制定类型为Array。

    String[] arrStr = ['Ananas', 'Banana', 'Kiwi']  
    
    assert arrStr instanceof String[]    
    assert !(arrStr instanceof List)
    
    def numArr = [1, 2, 3] as int[]    
    
    assert numArr instanceof int[]       
    assert numArr.size() == 3
    
    //多维数组
    
    def matrix3 = new Integer[3][3]         
    assert matrix3.size() == 3
    Integer[][] matrix2                     
    matrix2 = [[1, 2], [3, 4]]
    assert matrix2 instanceof Integer[][]

    Groovy不支持Java数组的初始化方式。

    9. Maps

    Map定义方式为:使用[]包括,里面的元素为key/value的形式,key和value以:分隔,每一对key/value以逗号分隔。Groovy穿件的map默认类型为java.util.LinkedHashMap。eg:

    def colors = [red: '#FF0000', green: '#00FF00', blue: '#0000FF']   
    
    assert colors['red'] == '#FF0000'    
    assert colors.green == '#00FF00'    
    
    colors['pink'] = '#FF00FF'           
    colors.yellow = '#FFFF00'       
    
    assert colors.pink == '#FF00FF'
    assert colors['yellow'] == '#FFFF00'
    
    assert colors instanceof java.util.LinkedHashMap

    Map中通过[key].key的方式来获取key对应的value。如果key不存在,则返回null。

    当我们使用数字作为key时,这个数字可以明确的认为是数字,并不是Groovy根据数字创建了一个字符串。但是如果以一个变量作为key的话,需要将变量用()包裹起来,否则key为变量,而不是变量所代表的值。eg:

    def key = 'name'
    def person = [key: 'Guillaume']     // key实际上为"key"
    
    assert !person.containsKey('name')   
    assert person.containsKey('key')  
    
    person = [(key): 'Guillaume']    // key实际上为"name"
    
    assert person.containsKey('name')    
    assert !person.containsKey('key')


    作者:losemycat
    链接:http://www.jianshu.com/p/f02b066bb055
    來源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    展开全文
  • groovy语言介绍

    千次阅读 2018-11-02 16:23:11
    1.什么是groovy?  Groovy是一种基于JVM(Java虚拟机)的敏捷开发语言,它结合了Python、Ruby和Smalltalk的许多强大的特性,Groovy 代码能够与 Java 代码很好地结合,也能用于扩展现有代码。由于其运行在 JVM 上的...

    1.什么是groovy?

           Groovy是一种基于JVMJava虚拟机)的敏捷开发语言,它结合了PythonRubySmalltalk的许多强大的特性,Groovy 代码能够与 Java 代码很好地结合,也能用于扩展现有代码。由于其运行在 JVM 上的特性,Groovy 可以使用其他 Java 语言编写的库。

           Groovy是一种基于Java平台的面向对象语言。 Groovy 1.0200712日发布,其中Groovy 2.4是当前的主要版本。 Groovy通过Apache License v 2.0发布。

          目前最新版本为2.5.3

    2.Groovy的特点

    Groovy中有以下特点:

    • 同时支持静态和动态类型
    • 支持运算符重载
    • 本地语法列表和关联数组
    • 对正则表达式的本地支持
    • 各种标记语言,如XMLHTML原生支持
    • Groovy对于Java开发人员来说很简单,因为JavaGroovy的语法非常相似
    • 您可以使用现有的Java
    • Groovy扩展了java.lang.Object

    动态类型

    类型对于变量,属性,方法,闭包的参数以及方法的返回类型都是可有可无的,都是在给变量赋值的时候才决定它的类型, 不同的类型会在后面用到,任何类型都可以被使用,即使是基本类型 (通过自动包装(autoboxing). 当需要时,很多类型之间的转换都会自动发生,比如在这些类型之间的转换: 字符串(String),基本类型(int) 和类型的包装类 (Integer)之间,可以把不同的基本类型添加到同一数组(collections)中。

    运算符重载

    运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。

    3.类

    Groovy类和java类一样,完全可以用标准java bean的语法定义一个Groovy类。但作为另一种语言,可以使用更Groovy的方式定义类,这样的好处是,可以少写一半以上的javabean代码。

    1)不需public修饰符

    如前面所言,Groovy的默认访问修饰符就是public,如果Groovy类成员需要public修饰,则根本不用写它。

    2)不需要类型说明

    同样前面也说过,Groovy也不关心变量和方法参数的具体类型。

    3)不需要getter/setter方法

    在很多ide(如eclipse)早就可以为程序员自动产生getter/setter方法了,在Groovy中,不需要getter/setter方法--所有类成员(如果是默认的public)根本不用通过getter/setter方法引用它们(当然,如果一定要通过getter/setter方法访问成员属性,Groovy也提供了它们)。

    4)不需要构造函数

    不再需要程序员声明任何构造函数,因为实际上只需要两个构造函数(1个不带参数的默认构造函数,1个只带一个map参数的构造函数--由于是map类型,通过这个参数可以构造对象时任意初始化它的成员变量)。

    5)不需要;结尾

    Groovy中每一行代码不需要分号作为结束符。

    4. 文件与类的关系

    Groovy中类和文件的对应关系并不像Java中那么固定(Java中一个文件只能有一个声明为public的类和其他一些非公共的类和内嵌类) 。在同一个groovy文件中可以包含多个public的类定义。具体规则如下:

    1、如果在一个groovy文件中没有任何类定义,它将被当做script来处理,也就意味着这个文件将被透明的转换为一个Script类型的类,这个自动转换得到的类将使用原始的groovy文件名(去掉扩展名,没有包名,在default包中)作为类的名字。groovy文件的内容被打包进run方法,另外在新产生的类中被加入一个main方法以进行外部执行该脚本。

    2、如果在groovy文件正好有一个类的定义,并且该类的名字与文件名称相同,那么这就和java中的类与文件的一一对应关系相同。

    3、在一个groovy文件中可以包含多个不同可见性的类定义,并且没有强制性的要求其中有一个类的类名与文件名相同。groovy编译器会很乐于把该文件中定义的所有的类都编译成*.class文件。如果希望能够直接调用这个groovy script,比如说在使用groovy命令行或者在某个IDE中执行,那么应该在该文件中的第一个类中定义一个main方法。

    4、在一个groovy文件中可以混合类的定义和脚本定义。在这种情况下,那些脚本代码将会变成直接调用的主类,所以在这种情况下不应该再定义一个和文件同名的类。

    5、在没有经过明确的编译过程即执行时,groovy将通过文件名来查找类。在这种情况下,名称将会很重要。Groovy只能找到那些和文件名匹配的类。在找到这种名字匹配的类时,找到的文件中定义的其他类将被解析并变得对groovy可见。

    5.语法

    基本类型

    • byte -这是用来表示字节值。例如2
    • short -这是用来表示一个短整型。例如10
    • int -这是用来表示整数。例如1234
    • long -这是用来表示一个长整型。例如10000090
    • float -这是用来表示32位浮点数。例如12.34
    • double -这是用来表示64位浮点数,这些数字是有时可能需要的更长的十进制数表示。例如12.3456565
    • char -这定义了单个字符文字。例如“A”
    • Boolean -这表示一个布尔值,可以是truefalse
    • String -这些是以字符串的形式表示的文本。例如,“Hello World”的。

     

    • BigInteger类型后缀为Gg
    • Long类型后缀为Ll
    • Integer类型后缀为Ii
    • Bigdecimal类型后缀为Gg
    • Double类型后缀为Dd
    • Float类型后缀为Ff

    与Java一致,但是可以不声明类型,使用def关键字。

    字符

    Groovy没有明确的字符类型,可以通过以下三种方式创建:

    1. char c1 = 'A'  // 类型声明为char
    2. assert c1 instanceof Character
    3.  
    4. def c2 = 'B' as char  // 通过as将类型强制指定为char
    5. assert c2 instanceof Character
    6.  
    7. def c3 = (char)'C'  // 通过类型转换
    8. assert c3 instanceof Character

    字符串

    Groovy中的字符串可以用单引号('),双引号()或三引号(”“”)括起来。此外,由三重引号括起来的Groovy字符串可以跨越多行

          String a = 'Hello Single'; 
          String b = "Hello Double"; 
          String c = "'Hello Triple" + "Multiple lines'";

    运算符

    • 算术运算符:+-*/、%、++--
    • 关系运算符:==!= <<=>>=
    • 逻辑运算符:&&||、!
    • 位运算符:&、|^

    • 赋值运算符:+=-=*=/=(%)=
    • 范围运算符:..

    范围

    Groovy支持java的范围方式,同时有自己的范围运算度”..”

    • 1..10 - 包含范围的示例
    • 1 ..<10 - 独占范围的示例
    • 'a'..'x' - 范围也可以由字符组成
    • 10..1 - 范围也可以按降序排列
    • 'x'..'a' - 范围也可以由字符组成并按降序排列。

    列表(List)

    列表是用于存储数据项集合的结构。在Groovy中,List保存了一系列对象引用。List中的对象引用占据序列中的位置,并通过整数索引来区分

    要处理列表中的数据,我们必须能够访问各个元素。 Groovy列表使用索引操作符[]索引。列表索引从零开始,这指的是第一个元素。

    • [11121314] - 整数值列表
    • ['Angular''Groovy''Java'] - 字符串列表
    • [12[34]5] - 嵌套列表
    • ['Groovy'212.11] - 异构的对象引用列表
    • [] - 一个空列表

    数组

    Groovy定义数组的方式和定义list的方式一样,只不过声明时需要制定类型,或者通过as来强制制定类型为Array

    Groovy不支持Java数组的初始化方式。

    1. String[] arrStr = ['Ananas', 'Banana', 'Kiwi'
    2.  
    3. def numArr = [1, 2, 3] as int[]   
    4.  
    5. //多维数组
    6. def matrix3 = new Integer[3][3]        

    映射(Map)

    映射(也称为关联数组,字典,表和散列)是对象引用的无序集合。Map集合中的元素由键值访问。 Map中使用的键可以是任何类。当我们插入到Map集合中时,需要两个值:键和值。

    Map中通过[key].key的方式来获取key对应的value。如果key不存在,则返回null

    • ['TopicName''Lists''TopicName''Maps'] - 具有TopicName作为键的键值对的集合及其相应的值。
    • [] - 空映射。

    闭包

    闭包是一个短的匿名代码块。它通常跨越几行代码。一个方法甚至可以将代码块作为参数。它们是匿名的。

             def clos = {println "Hello World"};

        clos.call(); 

    正则表达式

    Groovy使用~”pattern” 来支持正则表达式,它将使用给定的模式字符串创建一个编译好的Java Pattern 对象。Groovy也支持 =~(创建一个Matcher)和 ==~ (返回boolean,是否给定的字符串匹配这个pattern)操作符

    对于groups的匹配, matcher[index] 是一个匹配到的group字符串的List或者string

                                                                   正则表达式的辅助符号

                                                                  正则表达式的元字符

    XML及HTML支持

    Groovy 引入了一些全新的、更加合理的方法来创建和处理 XMLHTML。代码更加简洁,更具表达性。

    1. XML标记构建器  Groovy支持基于树的标记生成器BuilderSupport,它可以被子类化以生成各种树结构对象表示
    2. XML解析器 - Groovy XmlParser类使用一个简单的模型来将XML文档解析为Node实例的树。

    JSON

    1. JsonSlurper   JsonSlurper是一个将JSON文本或阅读器内容解析为Groovy数据的类结构,例如map,列表和原始类型,如整数,双精度,布尔和字符串。
    1. JsonOutput   此方法负责将Groovy对象序列化为JSON字符串

    数据库

    Groovygroovy-sql模块提供了比当前JavaJDBC技术更高级的抽象。Groovy sql API支持各种各样的数据库,其中一些如下所示。

    • HSQLDB
    • Oracle
    • SQL Server
    • MySQL
    • MongoDB
    展开全文
  • ◇ 具备丰富的C#/Java/Delphi/VB/C++/Python/Tcl/Groovy/Shell等开发及脚本开发经验◇ 具备20年的IT互联网工作经验。先后担任过项目经理,测试技术经理,测试总监以及专家级技术顾问等职务。独立开发完成有如下自动...
  • Groovy简介与使用

    万次阅读 2018-11-04 16:59:55
    Groovy语法特性(相比于Java) Groovy与Java项目集成使用 GroovyShell GroovyClassLoader GroovyScriptEngine JSR-223 Groovy实现相关原理 Groovy代码文件与class文件的对应关系 对于没有任何类定义 对于仅有一个...
    
    
    
    

    本文首发于简书 https://www.jianshu.com/p/2c6b95097b2c

    简介

    Groovy是构建在JVM上的一个轻量级却强大的动态语言, 它结合了Python、Ruby和Smalltalk的许多强大的特性.

    Groovy就是用Java写的 , Groovy语法与Java语法类似, Groovy 代码能够与 Java 代码很好地结合,也能用于扩展现有代码, 相对于Java, 它在编写代码的灵活性上有非常明显的提升,Groovy 可以使用其他 Java 语言编写的库.

    使用

    下载SDK

    • Groovy Console
    • 安装IDEA groovy插件

    应用

    ElasticSearch, Jenkins 都支持执行Groovy脚本
    项目构建工具Gradle就是Groovy实现的


    Groovy语法特性(相比于Java)

    1. 不需要分号

    2. return关键字可省略, 方法的最后一句表达式可作为返回值返回 (视具体情况使用, 避免降低可读性)

    3. 类的默认作用域是public, 不需要getter/setter方法

    4. def关键字定义的变量类型都是Object, 任何变量, 方法都能用def定义/声明 , 在 Groovy 中 “一切都是对象 "

    5. 导航操作符 ( ?. )可帮助实现对象引用不为空时方法才会被调用

      // java
      if (object != null) {
          object.getFieldA();
      }
      // groovy
      object?.getFieldA()
      
    6. 命令链, Groovy 可以使你省略顶级语句方法调用中参数外面的括号。“命令链”功能则将这种特性继续扩展,它可以将不需要括号的方法调用串接成链,既不需要参数周围的括号,链接的调用之间也不需要点号

      def methodA(String name) {
          println("A: " + name)
          return this
      }
      def methodB(String name) {
          println("B: " + name)
          return this
      }
      def methodC() {
          println("C")
          return this
      }
      def methodD(String name) {
          println("D: " + name)
          return this
      }
      
      methodA("xiaoming")
      methodB("zhangsan")
      methodC()
      methodD("lisi")
      
      // 不带参数的链中需要用括号 
      methodA "xiaoming" methodB "zhangsan" methodC() methodD "lisi"
      
    7. 闭包. 闭包是一个短的匿名代码块。每个闭包会被编译成继承groovy.lang.Closure类的类,这个类有一个叫call方法,通过该方法可以传递参数并调用这个闭包.

      def hello = {println "Hello World"}
      hello.call()
      
      // 包含形式参数
      def hi = {
          person1, person2 -> println "hi " + person1 + ", "+ person2
      }
      hi.call("xiaoming", "xiaoli")
      
      // 隐式单个参数, 'it'是Groovy中的关键字
      def hh = {
          println("haha, " + it)
      }
      hh.call("zhangsan")
      
    8. with语法, (闭包实现)

      // Java
      public class JavaDeamo {
          public static void main(String[] args) {
              Calendar calendar = Calendar.getInstance();
              calendar.set(Calendar.MONTH, Calendar.DECEMBER);
              calendar.set(Calendar.DATE, 4);
              calendar.set(Calendar.YEAR, 2018);
              Date time = calendar.getTime();
              System.out.println(time);
          }
      }
      // Groovy
      Calendar calendar = Calendar.getInstance()
      calendar.with {
          // it 指 calendar 这个引用
          it.set(Calendar.MONTH, Calendar.DECEMBER)
          // 可以省略it, 使用命令链
          set Calendar.DATE, 4
          set Calendar.YEAR, 2018
          // calendar.getTime()
          println(getTime())
          // 省略get, 对于get开头的方法名并且
          println(time)
      }
      
    9. 数据结构的原生语法, 写法更便捷

      def list = [11, 12, 13, 14] // 列表, 默认是ArrayList
      def list = ['Angular', 'Groovy', 'Java'] as List // 字符串列表
      // 同list.add(8)
      list << 8
      
      [1, 2, [3, 4], 5] // 嵌套列表
      ['Groovy', 21, 2.11] // 异构的对象引用列表
      [] // 一个空列表
      
      def set = ["22", "11", "22"] as Set // LinkedHashSet, as运算符转换类型
      
      def map = ['TopicName': 'Lists', 'TopicName': 'Maps'] // map, LinkedHashMap
      [:] // 空map
      
      // 循环
      map.each {
          print it.key
      }
      
    10. Groovy Truth

    所有类型都能转成布尔值,比如null, void 对象, 等同于 0 或空的值,都会解析为false,其他则相当于true

    1. groovy支持DSL(Domain Specific Languages领域特定语言), DSL旨在简化以Groovy编写的代码,使得它对于普通用户变得容易理解

      借助命令链编写DSL

      // groovy代码
      show = { println it }
      square_root = { Math.sqrt(it) }
      
      def please(action) {
        [the: { what ->
          [of: { n -> action(what(n)) }]
        }]
      }
      
      // DSL 语言: please show the square_root of 100  (请显示100的平方根)
      
      // 调用, 等同于:please(show).the(square_root).of(100)
      please show the square_root of 100
      // ==> 10.0
      
    2. Java 的 == 实际相当于 Groovy 的 is() 方法,而 Groovy 的 == 则是一个更巧妙的 equals()。 在Groovy中要想比较对象的引用,不能用 ==,而应该用 a.is(b)


    Groovy与Java项目集成使用

    项目中引入groovy依赖

                <dependency>
                    <groupId>org.codehaus.groovy</groupId>
                    <artifactId>groovy-all</artifactId>
                    <version>x.y.z</version>
                </dependency>
    

    常见的集成机制:

    GroovyShell

    GroovyClassLoader

    GroovyScriptEngine

    JSR 223 javax.script API

    GroovyShell

    GroovyShell允许在Java类中(甚至Groovy类)求任意Groovy表达式的值。您可使用Binding对象输入参数给表达式,并最终通过GroovyShell返回Groovy表达式的计算结果

    解析为脚本(groovy.lang.Script)运行

            GroovyShell groovyShell = new GroovyShell();
            groovyShell.evaluate("println \"hello world\"");
    

    GroovyClassLoader

    用 Groovy 的 GroovyClassLoader ,动态地加载一个脚本并执行它的行为。GroovyClassLoader是一个定制的类装载器,负责解释加载Java类中用到的Groovy类。

    GroovyClassLoader loader = new GroovyClassLoader();
    Class groovyClass = loader.parseClass(new File(groovyFileName)); // 也可以解析字符串
    GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance();
    groovyObject.invokeMethod("run", "helloworld");
    

    GroovyScriptEngine

    groovy.util.GroovyScriptEngine 类为 GroovyClassLoader 其上再增添一个能够处理脚本依赖及重新加载的功能层, GroovyScriptEngine可以从指定的位置(文件系统,URL,数据库,等等)加载Groovy脚本

    你可以使用一个CLASSPATH集合(url或者路径名称)初始化GroovyScriptEngine,之后便可以让它根据要求去执行这些路径中的Groovy脚本了.GroovyScriptEngine同样可以跟踪相互依赖的脚本,如果其中一个被依赖的脚本发生变更,则整个脚本树都会被重新编译和加载。

            GroovyScriptEngine groovyScriptEngine = new GroovyScriptEngine(file.getAbsolutePath());
            groovyScriptEngine.run("hello.groovy", new Binding())
    

    JSR-223

    JSR-223 是 Java 中标准的脚本框架调用 API。从 Java 6 开始引入进来,主要目用来提供一种常用框架,以便从 Java 中调用多种语言

    ScriptEngine groovyEngine = new ScriptEngineManager().getEngineByName("groovy");
    // 编译成类
    groovyEngine.compile(script)
    // 直接执行
    groovyEngine.eval(script)
    

    Groovy实现相关原理

    groovy负责词法、语法解析groovy文件,然后用ASM生成普通的java字节码文件,供jvm使用。

    Groovy代码文件与class文件的对应关系

    作为基于JVM的语言,Groovy可以非常容易的和Java进行互操作,但也需要编译成class文件后才能运行,所以了解Groovy代码文件和class文件的对应关系,有助于更好地理解Groovy的运行方式和结构。

    对于没有任何类定义

    如果Groovy脚本文件里只有执行代码,没有定义任何类(class),则编译器会生成一个Script的子类,类名和脚本文件的文件名一样,而脚本的代码会被包含在一个名为run的方法中,同时还会生成一个main方法,作为整个脚本的入口。

    对于仅有一个类

    如果Groovy脚本文件里仅含有一个类,而这个类的名字又和脚本文件的名字一致,这种情况下就和Java是一样的,即生成与所定义的类一致的class文件, Groovy类都会实现groovy.lang.GroovyObject接口。

    对于多个类

    如果Groovy脚本文件含有一个或多个类,groovy编译器会很乐意地为每个类生成一个对应的class文件。如果想直接执行这个脚本,则脚本里的第一个类必须有一个static的main方法。

    对于有定义类的脚本

    如果Groovy脚本文件有执行代码, 并且有定义类, 那么所定义的类会生成对应的class文件, 同时, 脚本本身也会被编译成一个Script的子类,类名和脚本文件的文件名一样


    Spring对Groovy以及动态语言的支持

    Spring 从2.0开始支持将动态语言集成到基于 Spring 的应用程序中。Spring 开箱即用地支持 Groovy、JRuby 和 BeanShell。以 Groovy、JRuby 或任何受支持的语言编写的应用程序部分可以无缝地集成到 Spring 应用程序中。应用程序其他部分的代码不需要知道或关心单个 Spring bean 的实现语言。

    动态语言支持将 Spring 从一个以 Java 为中心的应用程序框架改变成一个以 JVM 为中心的应用程序框架

    Spring 通过 ScriptFactory 和 ScriptSource 接口支持动态语言集成。ScriptFactory 接口定义用于创建和配置脚本 Spring bean 的机制。理论上,所有在 JVM 上运行语言都受支持,因此可以选择特定的语言来创建自己的实现。ScriptSource 定义 Spring 如何访问实际的脚本源代码;例如,通过文件系统, URL, 数据库。

    在使用基于 Groovy 的 bean 时,则有几种选择:

    • 将 Groovy 类编译成普通的 Java 类文件

    • 在一个 .groovy 文件中定义 Groovy 类或脚本

    • 在 Spring 配置文件中以内联方式编写 Groovy 脚本

    1. 配置编译的 Groovy 类, 和Java一样的用法, 定义groovy class, 使用<bean/>创建bean
    class Test {
        def printDate() {
            println(new Date());
        }
    }
    
        <bean id="test" class="com.qj.study.groovytest.spring.Test" />
    
    ClassPathXmlApplicationContext context = newClassPathXmlApplicationContext("applicationContext.xml");
    Test bean = (Test) context.getBean("test");
    bean.printDate();
    
    1. 配置来自 Groovy 脚本的 bean

      • <bean/>

      • <lang:groovy>

    • <bean/>示例:
     <bean id="demo" class="org.springframework.scripting.groovy.GroovyScriptFactory">
            <constructor-arg value="classpath:script/ScriptBean.groovy"/>
     </bean>
     <bean class="org.springframework.scripting.support.ScriptFactoryPostProcessor"/>
    
    • <lang:groovy/>示例:
        <lang:groovy id="demo" script-source="classpath:script/ScriptBean.groovy">
        </lang:groovy>
        <bean class="org.springframework.scripting.support.ScriptFactoryPostProcessor"/>
    

    实现过程:

    Groovy 语言集成通过 ScriptFactory 的 GroovyScriptFactory 实现得到支持

    当 Spring 装载应用程序上下文时,它首先创建工厂 bean(这里是GroovyScriptFactory 类型的bean)。然后,执行 ScriptFactoryPostProcessor bean中的postProcessBeforeInstantiation方法,用实际的脚本对象替换所有的工厂 bean。

    ScriptFactoryPostProcessor:

    	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
    		// 只处理ScriptFactory类型的bean
    		if (!ScriptFactory.class.isAssignableFrom(beanClass)) {
    			return null;
    		}
            // ...
            // 加载并解析groovy代码, 在scriptBeanFactory中注册BeanDefinition
    		prepareScriptBeans(bd, scriptFactoryBeanName, scriptedObjectBeanName);
            // ...
        }
    
    
         // prepareScriptBeans调用createScriptedObjectBeanDefinition
    	protected BeanDefinition createScriptedObjectBeanDefinition(BeanDefinition bd, String scriptFactoryBeanName,
    			ScriptSource scriptSource, @Nullable Class<?>[] interfaces) {
    
    		GenericBeanDefinition objectBd = new GenericBeanDefinition(bd);
    		objectBd.setFactoryBeanName(scriptFactoryBeanName);
            // 指定工厂方法, ScriptFactory.getScriptedObject, 创建脚本的Java对象 
    		objectBd.setFactoryMethodName("getScriptedObject");
    		objectBd.getConstructorArgumentValues().clear();
    		objectBd.getConstructorArgumentValues().addIndexedArgumentValue(0, scriptSource);
    		objectBd.getConstructorArgumentValues().addIndexedArgumentValue(1, interfaces);
    		return objectBd;
    	}
    

    创建bean的时候, SimpleInstantiationStrategy.instantiate

                     // 调用工厂方法创建beanInstance
    				Object result = factoryMethod.invoke(factoryBean, args);
    				if (result == null) {
    					result = new NullBean();
    				}
    
    

    GroovyScriptFactory.getScriptedObject

                          // 通过groovyClassLoader 加载并解析类
    					this.scriptClass = getGroovyClassLoader().parseClass(							scriptSource.getScriptAsString(), scriptSource.suggestedClassName());
    
    					if (Script.class.isAssignableFrom(this.scriptClass)) {
                              // 如果是groovy 脚本, 那么运行脚本, 将结果的类作为Bean的类型
    						Object result = executeScript(scriptSource, this.scriptClass);
    						this.scriptResultClass = (result != null ? result.getClass() : null);
    						return result;
    					}
    					else {
                              // 不是脚本, 直接返回类
    						this.scriptResultClass = this.scriptClass;
    					}
    
    	protected Object executeScript(ScriptSource scriptSource, Class<?> scriptClass) throws ScriptCompilationException {
    		try {
    			GroovyObject goo = (GroovyObject) ReflectionUtils.accessibleConstructor(scriptClass).newInstance();
    
                // GroovyObjectCustomizer 是一个回调,Spring 在创建一个 Groovy bean 之后会调用它。可以对一个 Groovy bean 应用附加的逻辑,或者执行元编程
    			if (this.groovyObjectCustomizer != null) {
    				this.groovyObjectCustomizer.customize(goo);
    			}
    
    			if (goo instanceof Script) {
    				// A Groovy script, probably creating an instance: let's execute it.
    				return ((Script) goo).run();
    			}
    			else {
    				// An instance of the scripted class: let's return it as-is.
    				return goo;
    			}
    		}
    		catch (NoSuchMethodException ex) {
                // ...
    	}
    

    最终在ScriptFactoryPostProcessor中, scriptBeanFactory保存了所有通过脚本创建的bean, scriptSourceCache缓存了所有的脚本信息

    	final DefaultListableBeanFactory scriptBeanFactory = new DefaultListableBeanFactory();
    
    	/** Map from bean name String to ScriptSource object */
    	private final Map<String, ScriptSource> scriptSourceCache = new HashMap<String, ScriptSource>();
    
    • refresh参数
    <lang:groovy id="refresh"  refresh-check-delay="1000"
                     script-source="classpath:script/RefreshBean.groovy">
        </lang:groovy>
    

    创建的是JdkDynamicAopProxy代理对象, 在每一次调用这个代理对象的方法的时候, 都回去校验被代理对象是否需要刷新, 通过比对脚本文件的最后更新时间和设定的更新时间间隔, 如果需要刷新则重新加载这个groovy文件, 并编译, 然后创建一个新的bean并注册进行替换

    3.内联方式配置

    inline script标签, 从配置中读取源代码

       <lang:groovy id="inline">
            <lang:inline-script> 
                <![CDATA[
                class InlineClass {
                    // xxxxx ...
                }
                ]]>
            </lang:inline-script>
        </lang:groovy>
    

    综上, 扩展一下, 脱离xml配置, 可以从数据库中定时加载groovy代码, 构建/更新/删除BeanDefinition


    Groovy运行沙盒

    沙盒原理也叫沙箱,英文sandbox。在计算机领域指一种虚拟技术,且多用于计算机安全技术。安全软件可以先让它在沙盒中运行,如果含有恶意行为,则禁止程序的进一步运行,而这不会对系统造成任何危害。

    举个例子:

    docker容器可以理解为在沙盒中运行的进程。这个沙盒包含了该进程运行所必须的资源。不同的容器之间相互隔离。CGroup实现资源控制, Namespace实现访问隔离, rootfs实现文件系统隔离。


    对于嵌入Groovy的Java系统, 如果暴露接口, 可能存在的隐患有

    • 通过Java的Runtime.getRuntime().exec()方法执行shell, 操作服务器…

    • 执行System.exit(0)

    • dump 内存中的Class, 修改内存中的缓存数据

    ElasticSearch Groovy 脚本 远程代码执行漏洞


    Groovy提供了编译自定义器(Compilation customizers), 无论你使用 groovyc 还是采用 GroovyShell 来编译类,要想执行脚本,实际上都会使用到编译器配置compiler configuration)信息。这种配置信息保存了源编码或类路径这样的信息,而且还用于执行更多的操作,比如默认添加导入,显式使用 AST(语法树) 转换,或者禁止全局 AST 转换, 编译自定义器的目标在于使这些常见任务易于实现。CompilerConfiguration 类就是切入点。


    groovy sandbox的实现 -> https://github.com/jenkinsci/groovy-sandbox

    实现过程:

    groovy-sandbox实现了一个SandboxTransformer, 扩展自CompilationCustomizer, 在Groovy代码编译时进行转换. 脚本转换后, 让脚本执行的每一步都会被拦截, 调用Checker进行检查

    可拦截所有内容,包括

    • 方法调用(实例方法和静态方法)
    • 对象分配(即除了“this(…)”和“super(…)”之外的构造函数调用
    • 属性访问(例如,z = foo.bar,z = foo。“bar”)和赋值(例如,foo.bar = z,foo。“bar”= z)
    • 数组访问和赋值

    当然, 执行性能也会受到一些的影响

    示例: Jenkins Pipline支持在Groovy沙盒中执行Groovy脚本
    image.png


    其他:

    Groovy元编程 原文 译文

    Groovy的ClassLoader体系

    展开全文
  • groovy&&集合 list

    2020-06-03 15:51:12
    一前一直没使用过groovy语言,但是在新的公司需要用到这个语言;不过还好,groovy是基于java之上的语言;学起来不是很吃力; 会一直更新新这篇文章。。。。。 刚开始的时候看到一个符号“<<” List<Byte>...

    一前一直没使用过groovy语言,但是在新的公司需要用到这个语言;不过还好,groovy是基于java之上的语言;学起来不是很吃力;
    会一直更新新这篇文章。。。。。
    刚开始的时候看到一个符号“<<”

    List<Byte> types = Lists.newArrayList()
                if (type == 3) {
                    types << (1 as byte)
                    types << (2 as byte)
                } else {
                    types << (byte) type
                }
    

    一开始很不理解,这不是按位运算符吗;啥意思啊我天;然后自己试了试:

    class SymbolDemo {
        static void main(String[] args) {
            def i = methdod01(2)
            println(i)
        }
        static def methdod01(Integer a){
            Integer type = 3
            List<Integer> list = Lists.newArrayList();
            list << 1
            list << 2
            list << 3
            if (a == 2){
                list << a
            }else {
                list << 5
            }
        }
    }
    

    看到这些代码应该就很明确了。这相当于list.add
    在这里插入图片描述需求是这样的一张图片;就是说需要从数据库中查书数据来,然后根据bug status(状态分组);

      List<BugStatusFindVo> bugStatusFindVos = Lists.newArrayList()
      List<Bug> bugs = bugService.findBugList(status, systemId, timeType, startTime, endTime)
            bugs.each {
                  Bug bug ->
                     bugStatusFindVos.each {
                         BugStatusFindVo statusFindVo ->
                             if (bug.status == statusFindVo.status){
                                statusFindVo.bugs << bug
                             }
                     }
            }
            bugStatusFindVos.each {
                it.bugNum = it.bugs.size()
            }
    

    BugStatusFindVo :实体类是这样的:

    class BugStatusFindVo implements Serializable{
    
        private static final long serialVersionUID = 8401342664443969084L
    
      Long bugNum
    
        Byte status
    
        String statusName
    
        List<Bug> bugs = Lists.newArrayList()
        }
    
    
    展开全文
  • Groovy集合(list)

    千次阅读 2018-03-28 10:39:41
    声明listlist = [1,2,3] list = (1..3).toList() //range转换为list assert list == [1,2,3] assert list[1] == 2 assert list instanceof java.util.List list[1] = 12 assert list == [1,12,3] ...
  • Groovy 操作符

    千次阅读 2019-01-24 00:25:16
    目录 1. 算术操作符 1.1 普通算术操作符 1.2 一元操作符 1.3 赋值算术操作符 2. 关系运算符 3. 逻辑运算符 3.1 优先级 3.2 短路特性 4. 位运算操作符 5. 条件运算符 5.1 非运算符 ...7. 正...
  • Groovy脚本基础全攻略

    万次阅读 多人点赞 2017-10-13 14:13:07
    点我开始Android技术交流】1 背景Groovy脚本基于Java且拓展了Java,所以从某种程度来说掌握Java是学习Groovy的前提,故本文适用于不熟悉Groovy却想快速得到Groovy核心基础干货的Java开发者(注意是Java),因为我的...
  • Groovy&Gradle总结

    千次阅读 2017-07-04 10:27:31
    0x01 Groovy 概述Groovy 是一个基于 JVM 的语言,代码最终编译成字节码(bytecode),并在 JVM 上运行。它具有类似于 Java 的语法风格,但是语法又比 Java 要灵活和方便,同时具有动态语言(如 ruby 和 Python)的...
  • Groovy基础:1: 简介

    千次阅读 2019-05-12 09:53:45
    Apache Groovy是一个功能强大的动态编程语言,靠着其简洁、与Java非常相似以及易于学习的语法,基于Java平台的Groovy关注于提高开发者的生产性。它可以和任何Java语言进行无缝集成,支持DSL,提供运行阶段和编译阶段...
  • Groovy入门教程

    万次阅读 多人点赞 2010-07-18 14:29:00
    Groovy入门教程kmyhy@126....作为跑在JVM中的另一种语言,groovy语法与 Java 语言的语法很相似。同时,Groovy 抛弃了java烦琐的文法。同样的语句,使用groovy能在最大限度上减少你的击键次数——这确实是“懒惰程序员
  • Groovy 使用完全解析

    万次阅读 多人点赞 2017-10-20 10:17:01
    概念Groovy是一种动态语言,它和Java类似(算是Java的升级版,但是又具备脚本语言的特点),都在Java虚拟机中运行。当运行Groovy脚本时它会先被编译成Java类字节码,然后通过JVM虚拟机执行这个Java字节码类。Groov
  • groovy

    2019-05-29 10:37:36
    http://groovy-lang.org/syntax.html https://jenkins.io/doc/book/pipeline/syntax/ https://jenkins.io/doc/pipeline/steps/ https://www.cnblogs.com/softidea/p/4368506.html https://www.w3cschool.cn...
  • Groovy入门

    2017-07-10 11:03:51
    groovy
  • Groovy

    2018-09-06 08:37:51
    -Groovy Before you learn, setup your IDE well!!! IDEA is recommanded. 1. Groovy基于JVM; 2.如果把java文件的后缀改成.groovy,能够编译通过并运行。但是由于groovy是动态语言,很多行为可能会不一致。...
  • groovy 兼容java的语法,同时有自己的特性 () ; 可以省略例如 println "hello" 可以定义弱类型 通过关键字def def temp=1 字符串有三种形式 没有 空指针异常错误 集合api 闭包特性 ...
  • Gradle从入门到实战 - Groovy基础

    万次阅读 多人点赞 2018-10-01 19:02:01
    前言 Android方向的第一期文章,会专注于Gradle系列,名字叫做『 Gradle从入门到实战』,计划有如下几个课程: Groovy基础 ...为什么是Groovy基础呢,因为玩转Gradle并不需要学习Groovy的全部...
  • Groovy 快速入门

    千次阅读 2017-03-05 16:15:17
    Groovy是一门基于JVM的动态语言,很多语法和Java类似。大部分Java代码也同时是合法的Groovy代码。本文是快速入门,所以针对语法并不会做非常详细的介绍。如果需要详细语法,请直接查看Groovy官方文档。另外为了省事...
  • Groovy使用字符串

    2017-07-19 23:07:45
    字面常量与表达式Groovy可以使用单引号创建字符串字面常量,比如’hello’。而java中,’a’是一个char,”a”才是一个String对象,Groovy中没有这样的分别。在Groovy中,二者都是String类的实例。如果想显式地创建一...
1 2 3 4 5 ... 20
收藏数 66,269
精华内容 26,507
关键字:

groovy