前言

Why

初次接触到Groovy是在实习中接触到一个 纯Groovy写的项目,当时看了下这不就是没有分号的Java么,而且也是有年纪的语言了,并不想投入时间学习。后来工作中越来越多的看到Groovy的身影,Gradle,Spring Cloud Contract等等都支持Groovy作为DSL(领域专用语言),同时Groovy在测试领域也有一席之地,因为语法简单,可以很快捷的编写Test Case,总之可以把Groovy看作Java的小伙伴,好帮手。

What

Groovy是JVM平台上的一种面向对象且同时支持静态动态的脚本语言,语法和Java区别不大,提供了一些语法糖,代码的表达能力更强。默认小伙伴们都已经有了Java基础,本文主要介绍Groovy比Java多出的语法糖,以及使用较多的DSL。

语法糖

大致了解一些语法糖可以更舒服的看DSL

可以用def关键字定义变量和方法,编译期做类型推断

多变量同时创建

def (aa, bb) = [1, 2]

范围创建

int[] range = 0..10;

支持for in写法

for(variable in range) {

statement #1

statement #2

}

方法参数支持默认值

def someMethod(parameter1, parameter2 = 0, parameter3 = 0) {

// Method code goes here

}

字符串支持单引号和双引号,类似于shell,python,双引号中可识别变量

列表创建

List strings = ["g", "r", "o", "o", "v", "y"]

map创建

Map stringMap = ["name": "wang", "age": "99"]

正则表达式,~后面直接跟正则语句,可直接用于判断

if ( "Groovy" =~ "^G")

trait关键字声明一个可以有属性和默认实现的接口,Java8之后的接口也都能达到同样效果

支持闭包,自己Call自己

def closure = { param -> println "Hello ${param}" };

closure.call("World");

10.times {num -> println num}

函数科里化贼方便

def cl1 = {int a, b, c ->

a + b + c

}

def cl1Curry1 = cl1.curry(1)

调用shell方便

println "ls -l".execute().text

instanceof可以简写成in

DSL

链式调用

在不产生歧义的情况下我们可以省略方法调用中的括号,使代码更像说话

// equivalent to: turn(left).then(right)

turn left then right

// equivalent to: take(2.pills).of(chloroquinine).after(6.hours)

take 2.pills of chloroquinine after 6.hours

// equivalent to: paint(wall).with(red, green).and(yellow)

paint wall with red, green and yellow

// with named parameters too

// equivalent to: check(that: margarita).tastes(good)

check that: margarita tastes good

// with closures as parameters

// equivalent to: given({}).when({}).then({})

given { } when { } then { }

运算符重载

Operator

Method

a + b

a.plus(b)

a - b

a.minus(b)

a * b

a.multiply(b)

a ** b

a.power(b)

a / b

a.div(b)

a % b

a.mod(b)

a | b

a.or(b)

a & b

a.and(b)

a ^ b

a.xor(b)

a++ or ++a

a.next()

a-- or --a

a.previous()

a[b]

a.getAt(b)

a[b] = c

a.putAt(b, c)

a << b

a.leftShift(b)

a >> b

a.rightShift(b)

a >>> b

a.rightShiftUnsigned(b)

switch(a) { case(b) : }

b.isCase(a)

if(a)

a.asBoolean()

~a

a.bitwiseNegate()

-a

a.negative()

+a

a.positive()

a as b

a.asType(b)

a == b

a.equals(b)

a != b

! a.equals(b)

a <=> b

a.compareTo(b)

a > b

a.compareTo(b) > 0

a >= b

a.compareTo(b) >= 0

a < b

a.compareTo(b) < 0

a <= b

a.compareTo(b) <= 0

脚本基类

我们运行的Groovy脚本在编译过程中都自动继承了 groovy.lang.Script 这个抽象类,并把脚步内容绑定到run方法中执行。

可以通过创建一个Binding在脚本和基类中创建公用的变量

def binding = new Binding()

def shell = new GroovyShell(binding)

binding.setVariable('x',1)

binding.setVariable('y',3)

shell.evaluate 'z=2*x+y'

assert binding.getVariable('z') == 5

可以自定义基类

class BaseScript extends Script{

String name

public void greet() { println "Hello, $name!" }

@Override

Object run() {

greet()

}

}

@BaseScript demo.BaseScript baseScript

setName "100"

greet()

@DelegatesTo

是一个文档与编译时注释,当我们使用了委托模式去执行闭包时,文档生成,IDE以及类型推断都无法准确知道闭包具体被委托到哪里执行,我们就需要使用此注解显示声明。

当我们要实现如下效果时,我们需要定义一个email方法接受一个闭包,然后通过构建模式创建一个EmailSpec,去初始化并且委托执行闭包

email {

from 'dsl-guru@mycompany.com'

to 'john.doe@waitaminute.com'

subject 'The pope has resigned!'

body {

p 'Really, the pope has resigned!'

}

}

def email(@DelegatesTo(strategy=Closure.DELEGATE_ONLY, value=EmailSpec) Closure cl) {

// ...

}

当我们要委托给方法的另一个参数时可以

def exec(@DelegatesTo.Target Object target, @DelegatesTo Closure code) {

// rehydrate方法创建一个闭包副本

def clone = code.rehydrate(target, this, this)

clone()

}

自定义编译器

增加默认导入,并且支持别名

import org.codehaus.groovy.control.customizers.ImportCustomizer

def icz = new ImportCustomizer()

// "normal" import

icz.addImports('java.util.concurrent.atomic.AtomicInteger', 'java.util.concurrent.ConcurrentHashMap')

// "aliases" import

icz.addImport('CHM', 'java.util.concurrent.ConcurrentHashMap')

// "static" import

icz.addStaticImport('java.lang.Math', 'PI') // import static java.lang.Math.PI

// "aliased static" import

icz.addStaticImport('pi', 'java.lang.Math', 'PI') // import static java.lang.Math.PI as pi

// "star" import

icz.addStarImports 'java.util.concurrent' // import java.util.concurrent.*

// "static star" import

icz.addStaticStars 'java.lang.Math' // import static java.lang.Math.*

可用于限制AST的级别,比如使用者不能用闭包,不允许导入其他包等等

构建

Groovy内置了很多好用的构建器,具体使用查看官方教程

[官方教程](

java and dsl_Groovy语法糖以及DSL相关推荐

  1. 浅析java中的语法糖

    概述 编译器是一种计算机程序, 它主要的目的是将便于人编写.阅读.维护的高级计算机语言所写的源代码程序, 翻译为计算机能解读.运行的低阶机器语言的程序, 即可执行文件.而 javac 就是java语言 ...

  2. 阿里云面试:什么是语法糖?Java中有哪些语法糖?

    点击上方"芋道源码",选择"设为星标" 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | ...

  3. 什么是语法糖?Java中有哪些语法糖?

    本文从 Java 编译原理角度,深入字节码及 class 文件,抽丝剥茧,了解 Java 中的语法糖原理及用法,帮助大家在学会如何使用 Java 语法糖的同时,了解这些语法糖背后的原理 1 语法糖 语 ...

  4. Java 中的语法糖,真甜。

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 我们在日常开发中经常会使用到诸如泛型.自动拆箱和装箱.内部 ...

  5. Java 13个语法糖梳理总结

    0. 前言 为什么需要语法糖?语法糖可以让程序更加简洁,有更高的可读性.举个不太恰当但是可以说明问题的例子,很多饭店每天需要买菜,一般的买菜单都是由厨师手写的,而有些蔬菜的名字比较难写,所以他们在写的 ...

  6. java里面的语法糖(糖衣语法)

    语法糖是一种用来方便程序员代码开发的手段,简化程序开发,但是不会提供实质性的功能改造,但可以提高开发效率或者语法的严谨性或者减少编码出错的机会. 总而言之,语法糖可以看作是编译器实现的一种小把戏. 语 ...

  7. Java 中的语法糖 (Syntactic Sugar)

    语法糖(Syntactic Sugar),也叫糖衣语法,是英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语.指的是,在计算机语言中添加某种语法,这种语法能使程序员更方便 ...

  8. Java中的语法糖及反编译工具

    雪压枝头低,虽低不着泥 壹·Java中的反编译工具 贰·常见的12"颗"语法糖 switch forEach lambda if条件编译 变长参数 enum assert断言 tr ...

  9. java实验Lambda语法糖_Java: 语法糖 -- Lambda

    Lambda是Java 8引入的新特性,在Java语法层面,Lambda表达式允许函数作为一个方法的参数(函数作为参数传递到方法中):在具体实现上主要依靠了JVM底层提供的 Lambda相关API ( ...

最新文章

  1. Java SE 第十六讲----面向对象特征之继承
  2. leetcode算法题--Group Anagrams
  3. wireshark网络分析就这么简单 pdf_才知道,PDF、Excel、Word互转这么简单?涨知识了...
  4. 升级python3后yum出现异常解决办法
  5. python的threading库_python标准库介绍——31 threading 模块详解
  6. storm的消息格式分析
  7. 春天:注入列表,地图,可选对象和getBeansOfType()陷阱
  8. Linux 命令之 killall 命令-使用进程的名称来杀死一组进程
  9. spring学习(40):注入数组类型
  10. [Jobdu] 题目1527:首尾相连数组的最大子数组和
  11. 智慧讲台必须支持的协议
  12. SpringBoot使用@Transactional
  13. 山寨高仿iPad难现山寨手机的辉煌
  14. php网页登录制作,thinkphp5 系统登录的实现
  15. .NET连接SQL Server
  16. 笔记本BIOS启动项中找不到新装的固态硬盘解决
  17. Android手机屏幕投影到电脑工具
  18. win10的计算机 桌面图标不见了怎么办,Win10我的电脑怎么放在桌面?Win10此电脑图标不见了的解决方法...
  19. FreeSurfer和FSL的安装和使用(脑部图像去除头骨+对图像和label同时进行仿射对齐)教程
  20. 高中计算机课程教程,高中信息技术课教学计划

热门文章

  1. 甲骨文提供免费HR工具,助力客户保障员工安全
  2. 抗疫进展:多家科研机构联合筛选出五种可能有效的抗病毒药物
  3. 十年云计算大爆发,微软正在摧毁其它竞争对手
  4. 如何成为云计算专家?这些必须知道
  5. android xml左边,Android XML – 如何将项目对齐到最左侧,中间和最右侧
  6. 自定义控件android.r,Android控件架构与自定义控件
  7. apache日志导入mysql,将Apache访问日志记录到Mysql数据库中
  8. 【Java线程池】Java线程池汇总,看这一篇文章就够了
  9. 企业实战(Jenkins+GitLab+SonarQube)_04_Jenkins安装推荐插件
  10. npm如何设置淘宝镜像