groovy 学习笔记

栏目: Groovy · 发布时间: 5年前

内容简介:默认支持JAVA语法,所以所有it 是什么? upto方法接受一个闭包参数,如果闭包只需要一个参数,在groovy中可以使用默认的名字it来标示该参数, 切记用times 是默认从0开始,upto 是给定上限
  • java.lang
  • java.util
  • java.io
  • java.net
  • java.math.BigDecimal
  • java.math.BigInteger
  • groovy.lang
  • groovy.util

轻量级Java

  • Return 可选
  • 分号分隔符可选
  • 方法和类默认是public
  • ?. 只分派不为null的对象
  • 可以使用具名参数初始化javaBean
  • 不需要捕获自己不关心的异常
  • static方法也可以使用this来引用Class

GROOVY 语法

默认支持 JAVA 语法,所以所有 .groovy 文件中可以使用JAVA语法

循环

  • range
for (i in 0..10) {
    println i
}
  • upto
0.upto(10) {
    println it
}

it 是什么? upto方法接受一个闭包参数,如果闭包只需要一个参数,在groovy中可以使用默认的名字it来标示该参数, 切记用

  • times
10.times {
    print(it)
}

times 是默认从0开始,upto 是给定上限

  • step
0.step(10, 2) {
    print(it)
}

步长 0~10 步长2

安全导航操作

  • ?.
def foo(str) {
    str?.reverse()
}

println foo('hello')

str 不为null,则调用 str.reverse(), 这里包含了dolast未默认返回值的动作

异常处理

  • 可以不显式catch异常, 自动向上抛
def openFile(fileName) {
    new FileInputStream(fileName)
}
def openFile(fileName) {
    try {
        new FileInputStream(fileName)
    } catch (ex) {
        println(ex)
    }
}

变量ex前面没有任何类型, 代表可以捕获任何异常, 但是注意: 不能捕获除Exception之外的Error或者Throuwable, 要捕获的话需要显示声明 catch (Trowable th)

javaBean

class Two {
    def final name
    private def address

    Two(name) {
        this.name = name
    }

//    void setAddress(newAddress) {
//        throw new IllegalAccessException("error")
//    }
}

def two = new Two('gc')
// two.name = 'gc2' 会抛异常
two.address = '222' //不会抛异常,如果需要限制, 需要重写 setAddress方法
println("$two.name")
println("$two.address")

灵活的初始化和具名参数

class Two {
    def final name
    private def address
    def x, y, z

//    void setAddress(newAddress) {
//        throw new IllegalAccessException("error")
//    }
}

// def two = new Two(name: 'gc', address: 'add', x: 1, y: 2, z: 3) 会报错,因为这个操作并不是构造器,所以会在构造器之后执行
def two = new Two(address: 'add', x: 1, y: 2, z: 3)
// two.name = 'gc2' 会抛异常
two.address = '222' //不会抛异常,如果需要限制, 需要重写 setAddress方法
println("$two.name")
println("$two.address")
println("$two.z")
println("$two.x")
println("$two.y")
def access(x, y, z) {
    println "$x, $y, $z"
}

access(1, 2, 3)
access(x: 1, y: 2, z: 3, 50, true)
access(50, true, x: 1, y: 2, z: 3)

//1, 2, 3
////[x:1, y:2, z:3], 50, true
////[x:1, y:2, z:3], 50, true

如果groovy方法实参中存在map,则会自动将map传递给第一个形参, 如果要强制哪个参数为map, 可以 access(x, Map y, z) 这样写

可选形参

def access(x, y = 'y', z = 10) {
    println "$x, $y, $z"
}

access(1)

access(1, 2)

access(1, 2, 3)

这里可选形参必须放在参数列表末尾, 方便在固有接口中增加参数,便于接口演进设计

def access(x, y = 'y', z = 10, String[] args) {
    println "$x, $y, $z, $args"
}

access(1)

access(1, 2)

access(1, 2, 3)

access(1, 2, 3, '4', '5')

groovy 可以把参数最末尾的数组列表设置为可选的, 注意数组列表必须放在实参最末尾

多赋值

def access(str1, str2) {
    [str1, str2] // 最后一句未默认返回, 这里必须返回数组
}

def (str1, str2) = access("gc1", "gc2") // 接受返回值的外面可以把数组拆开
def args1 = access("gc1", "gc2") // 也可以不拆开

println("$str1, $str2")
println("$args1")

//gc1, gc2
//[gc1, gc2]

这样交换变量就变得很方便

def access(str1, str2) {
    [str2, str1]
}

def (str1, str2) = access("gc1", "gc2")

println("$str1, $str2")

//gc2 , gc1

如果左侧变量和右侧返回值数量一样,则一一映射,如果右面比左面多,则丢弃, 如果左面比右面多,则附null

如果左面的变量类型为基本类型,则附值为null的时候会抛异常 因为 int x = null 是非法的

实现接口

interface A {
    void aOne(str)

    void aTwo()

    void aThree(str1, str2, str3)
}

def useA(A a) {
    a.aOne("hello")
    a.aTwo()
//    a.aThree(1, 2, 3) // 将会异常, 因为在调用的时候无法区分it到底是哪个参数
}

useA({ println(it) } as A)

/**
 hello
 null
 **/

groovy 并不强制实现接口中的所有方法,只需要实现自己关心的方法就行, 如果确定为未实现的方法永远不会被调用,则没有问题, 否则会有异常

interface A {
    void aOne(str)

    void aTwo()
}

def useA(A a) {
    a.aOne("hello")
    a.aTwo()
}

useA({
    aOne:
    {
        println(it)
    }
    aTwo:
    {
        println("hello world")
    }

} as A)

/**
 hello
 hello world"
 **/

如果要实现的接口中由多个方法且实现姿势不一样,可以用 {methodName: {methodBody}, ....} 的姿势来实现

interface AI {
    void methodOne()
}

interface AII {
    void methodOne(str)
}

class B {
    def useA(AI a) {
        a.methodOne();
    }
}

B b = new B()
def methodName = "useA"
def interfaceName = "AI"

b."$methodName"({ print("hello world") }.asType(Class.forName("$interfaceName"))) // 注意,这里不能使用 '$interfaceName' 单引号

上面的方法使用了动态的实现接口的方法

Bool求值

def bool1 = 1
def bool2 = "hello"
def bool3 = []


if (bool1) {
    print(bool1)
}
if (bool2) {
    print(bool2)
}
if (bool3) {
    print(bool3)
}

groovy 不像java对bool值那么挑剔,以下表中列举了类型与布尔值的对应关系

类型 为真的条件
Boolean true
Collection 集合不为空
Character 值不为0
CharSequence 长度不为0
Iterator hasNext为true
Number double不为0
Map 不为空
Matcher 至少有一个匹配
Object[] 长度大于0
其他任何类型 引用不为null

操作符重载

在groovy中,每一个操作符都映射到一个标准方法,这些方法在java中可以直接使用,在groovy中即可以使用方法,也可以使用操作符


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Pro Django

Pro Django

Marty Alchin / Apress / 2008-11-24 / USD 49.99

Django is the leading Python web application development framework. Learn how to leverage the Django web framework to its full potential in this advanced tutorial and reference. Endorsed by Django, Pr......一起来看看 《Pro Django》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具