groovy语言简介

  • 一种基于JVM的敏捷开发语言,作为编程语言可编译成java字节码,也可以作为脚本语言解释执行。
  • 结合了Python、Ruby和Smalltalk的许多强大的特性
  • 支持面向对象编程也支持面向过程编程
  • 支持动态类型,闭包等语言特性
  • 无缝集成所有已经存在的java类库

groovy环境搭建

参考官网groovy环境搭建

groovy的hello world

在groovy语言中,如下两种写法效果完全相同

版本1:

class HelloGroovy {public static void main(String[] args) {System.out.println("hello groovy!");}
}

版本2:

print "hello groovy"

版本2看起来是脚本,其实是编译器帮我们变成了class,版本2脚本对应的class反编译为如下代码:

import groovy.lang.Binding;
import groovy.lang.Script;
import org.codehaus.groovy.runtime.InvokerHelper;
public class HelloGroovy extends Script {public HelloGroovy() {}public HelloGroovy(Binding context) {super(context);}public static void main(String... args) {InvokerHelper.class.invoke<invokedynamic>(InvokerHelper.class, HelloGroovy.class, args);}public Object run() {return this.invoke<invokedynamic>(this, "hello groovy");}
}

我们直观感受一个是编译语言,一个是脚本语言,但其实最后都是编译执行的。

groovy基础语法

变量

变量类型:全部为对象类型,不存在基本类型,基本类型的定义都会被转化为对象类型。

package variable
int x = 10
println x.class
double y = 3.14
println y.class

输出为:

class java.lang.Integer
class java.lang.Double

变量定义:强类型和弱类型def定义

def x_1 = 3.1415
println x_1.class

def定义时,会根据值的类型将变量转化为对应类型,重新赋值为其他数据类型的值,则变量类型也会变为其他数据类型

建议:内部使用的变量建议使用def定义,而提供给外部程序使用的变量,则建议使用强类型

字符串

StringGString

字符串使用单引号、双引号和三个单引号定义都等同为String,区别:

  • 单引号没有格式,格式需要转义,比如换行需要拼接;三个单引号可以直接指定格式
  • 单引号不能引入扩展表达式,双引号可以在字符串中引入扩展表达式。如果双引号存在扩展表达式,类型则为GString
//def name = 'a single \'a\'string'
//println name.classdef thupleName = '''\
line one
line two
line three
'''
//println thupleNamedef doubleName = "this a common String"
//println doubleName.classdef name = "Qndroid"
def sayHello = "Hello: ${name}"
//println sayHello
//println sayHello.classdef sum = "the sum of 2 and 3 equals ${2 + 3}" //可扩展做任意的表达式
//println sum

String方法来源:

java.lang.String,常用java类型,比较熟悉了

DefaultGroovyMethods,groovy所有类型都有的方法

StringGroovyMethods,继承DefaultGroovyMethods,有普通类型的参数和闭包类型的参数

package org.codehaus.groovy.runtime;
...
public class StringGroovyMethods extends DefaultGroovyMethodsSupport {
...

groovy新增的部分string方法如下:

/* ==================字符串的方法=================== */
def str = "groovy Hello"
//println str.center(8)
//println str.padLeft(8, 'a')
def str2 = 'Hello'
//println str > str2
//println str[0]
//println str[0..1]
//println str - str2//println str.reverse()
//println str.capitalize()

逻辑控制

//对范围的for循环
def sum = 0
for (i in 0..9) {sum += i
}
//println sum
sum = 0
/*** 对List的循环*/
for (i in [1, 2, 3, 4, 5, 6, 7, 8, 9]) {sum += i
}
/*** 对Map进行循环*/
for (i in ['lili': 1, 'luck': 2, 'xiaoming': 3]) {sum += i.value
}

方法调用

方法如果只有一个参数,可以省略()

groovy闭包

闭包定义、调用和返回值

闭包就是一段代码块,代码块用{ }表示

def clouser = { println "hello groovy!" }
//闭包调用
//clouser.call()
clouser()

闭包普通参数和隐式参数

->之前就是参数部分,可以为空(没有参数)

//普通参数
def clouser = { String name -> println "hello ${name}!" }
//闭包调用
//clouser.call()def name = 'groovy!'
clouser(name)//多个参数
def clouser = {String name, int age -> println "hello ${name}, My age is ${age}"
}
def name = 'groovy!'
clouser(name,4)//默认隐式参数 it
def clouser = { println "hello ${it}"}
def name = 'groovy!'
clouser(name)

闭包的返回值

如果有return语句,则返回对应值,如果没有return语句,则返回null

闭包的用法

与基本类型的结合,闭包参数需要查看源码,看需要传入的参数

int x = fab(5)
println x
//用来求指点number的阶乘
int fab(int number) {int result = 11.upto(number, {num -> result *= num})return result
}
//结果为120int cal(int number) {int result = 0number.times {num -> result += num}return result
}

upto源码

public static void upto(Number self, Number to, @ClosureParams(FirstParam.class) Closure closure) {int self1 = self.intValue();int to1 = to.intValue();if (self1 <= to1) {for (int i = self1; i <= to1; i++) {closure.call(i);}} elsethrow new GroovyRuntimeException("The argument (" + to +") to upto() cannot be less than the value (" + self + ") it's called on.");
}

与String结合

String str = 'the 2 and 3 is 5'
//each的遍历,返回值为本身
str.each {String temp -> print temp
}
//find 来查找符合条件的第一个
str.find {String s-> s.isNumber()
}

find源码

public static Object find(Object self, Closure closure) {BooleanClosureWrapper bcw = new BooleanClosureWrapper(closure);for (Iterator iter = InvokerHelper.asIterator(self); iter.hasNext();) {Object value = iter.next();if (bcw.call(value)) {return value;}}return null;
} 

与数据结构结合

与文件等结合

闭包进阶

闭包关键变量this

闭包关键变量owner

闭包关键变量delegate

/*** 闭包的三个重要变量:this,owner,delegate*/
def scriptClouser = {println "scriptClouser this:" + this //闭包定义处的类println "scriptClouser owner:" + owner //闭包定义处的类或者对象println "scriptClouser delegate:" + delegate //任意对象,默认为owner一致
}
scriptClouser.call()//this为闭包定义处的类,//定义了一个内部类,在脚本类中
class Person {def static classClouser = {println "classClouser this:" + thisprintln "classClouser owner:" + ownerprintln "classClouser delegate:" + delegate}def static say() {def classClouser = {println "methodClassClouser this:" + thisprintln "methodClassClouser owner:" + owner println "methodClassClouser delegate:" + delegate}classClouser.call()}
}
Person.classClouser.call()
Person.say()//闭包中定义一个闭包
def nestClouser = {def innerClouser = {println "innerClouser this:" + thisprintln "innerClouser owner:" + owner println "innerClouser delegate:" + delegate}innerClouser.call()
}
nestClouser.call()

闭包的委托策略

/*** 闭包的委托策略*/
class Student {String namedef pretty = { "My name is ${name}"}String toString() {pretty.call()}
}
class Teacher {String name
}
def stu = new Student('Sarash')
def tea = new Teacher('Ondroid')
stu.pretty.delegate = tea
stu.pretty.resolveStrategy = Closure.DELEGATE_FIRST
println stu.toString() 

常见数据结构使用

列表的定义

//def list = new ArrayList() //java的定义方式
def list = [1, 2, 3, 4, 5]
println list.class
println list.size()
def array = [1, 2, 3, 4, 5] as int[]
int[] array2 = [1, 2, 3, 4, 5]

列表的操作:原理为操作ArrayList

映射map的定义

//def map = new HashMap()
def colors = [red  : 'ff0000',green: '00ff00',blue : '0000ff']
//索引方式
//println colors['red']
//println colors.red
colors.blue
//添加元素
//colors.yellow = 'ffff00'
colors.complex = [a: 1, b: 2]
//println colors.getClass()

范围range的定义和使用

def range = 1..10
//println range[0]
//println range.contains(10)
println range.from
println range.to//遍历
range.each {// println it
}for (i in range) {//  println i
}def result = getGrade(75)
println resultdef getGrade(Number number) {def resultswitch (number) {case 0..<60:result = '不及格'breakcase 60..<70:result = '及格'breakcase 70..<80:result = '良好'breakcase 80..100:result = '优秀'break}return result
}

面向对象特性

类、接口等的定义和使用

类:

  1. groovy中默认都是public
  2. 无论你是直接还是调用get/set,最终都是调用get/set

接口:

接口中不许定义非public的方法

Trait:

和接口一样,唯一不同是可以有默认实现

元编程

方法寻找流程

  1. 类中是否有此方法
  2. MetaClass中是否有此方法
  3. 是否重写了methodMissing()
  4. 是否重写了InvokeMathod()
  5. Throw MissingMethodException

为类动态的添加一个属性

Person.metaClass.sex = 'male'

为类动态的添加方法

Person.metaClass.nameUpperCase = { -> sex.toUpperCase()}

为类动态的添加静态方法

Person.metaClass.static.createPerson = {}

高级用法实战

json文件处理及json,model互转

代码样例:

import groovy.json.JsonOutput
import groovy.json.JsonSlurper
import objectorention.Person//def json = JsonOutput.toJson(list)
def reponse =getNetworkData('http://xxx.json')println reponse.data.head.namedef getNetworkData(String url) {//发送http请求---完全是使用java库def connection = new URL(url).openConnection()connection.setRequestMethod('GET')connection.connect()def response = connection.content.text//将json转化为实体对象def jsonSluper = new JsonSlurper()return jsonSluper.parseText(response)
} 

xml文件读取

代码样例:

import groovy.xml.MarkupBuilderfinal String xml = '''<response version-api="2.0"><value><books id="1" classification="android"><book available="20" id="1"><title>疯狂Android讲义</title><author id="1">李刚</author></book><book available="14" id="2"><title>第一行代码</title><author id="2">郭林</author></book><book available="13" id="3"><title>Android开发艺术探索</title><author id="3">任玉刚</author></book><book available="5" id="4"><title>Android源码设计模式</title><author id="4">何红辉</author></book></books><books id="2" classification="web"><book available="10" id="1"><title>Vue从入门到精通</title><author id="4">李刚</author></book></books></value></response>
'''//开始解析此xml数据
def xmlSluper = new XmlSlurper()
def response = xmlSluper.parseText(xml)//println response.value.books[0].book[0].title.text()
//println response.value.books[0].book[0].author.text()
//println response.value.books[1].book[0].@availabledef list = []
response.value.books.each { books ->//下面开始对书结点进行遍历books.book.each { book ->def author = book.author.text()if (author.equals('李刚')) {list.add(book.title.text())}}
}
//println list.toListString()//深度遍历xml数据
def titles = response.depthFirst().findAll { book ->return book.author.text() == '李刚' ? true : false
}
//println titles.toListString()//广度遍历xml数据
def name = response.value.books.children().findAll { node ->node.name() == 'book' && node.@id == '2'
}.collect { node ->return node.title.text()
}//println name

普通文件的读写

java文件处理

  1. 节点流:InputStream,OutputStream及其子类
  2. 处理流:ReaderWriter及其子类

所有java对文件的处理类,groovy都可以使用

groovy扩展了许多更加快捷和强大的方法

代码示范:

def file = new File(pathname:'../../test.txt')
file.eachline { line ->println line
}def text = file.getText()
println textdef result = file.readLines()//读取文件部分内容
def reader = file.withReader { reader ->char[] buffer = new char[100]reader.read(buffer)return buffer
}
println reader
def copy(String sourcePath, String destationPath) {try {//首先创建目标文件def desFile = new File(destationPath)if (!desFile.exists()) {desFile.createNewFile()}//开始copynew File(sourcePath).withReader { reader ->def lines = reader.readLines()desFile.withWriter { writer ->lines.each { line ->writer.append(line + "\r\n")}}}return true} catch (Exception e) {e.printStackTrace()}return false
} 

groovy与java对比

  • 没有java那么多的限制
  • 对java的功能进行了极大的扩展
  • 既可以编写应用,也可以编写脚本

语法上区别:

  • Groovy 语句可以不用分号结尾
  • 定义变量的时候可以不指定其类型、Groovy 中函数的返回值也可以是无类型的
  • 最后一行代码的执行结果就是函数的返回值
  • 如果指定了函数返回类型,则可不必加 def 关键字来定义函数
  • Groovy中函数调用的时候还可以不加括号
  • 闭包是一段代码,所以需要用花括号括起来
  • -> 箭头前面是参数定义,箭头后面是代码
  • Groovy 中,当函数的最后一个参数是闭包的话,可以省略圆括号或闭包放在后面
  • 如果发送的实参的个数多于方法的形参个数,而且多出的实参是名值对,那么Groovy会假设方法的第一个形参是一个Map,然后将实参列表中的所有名值对组织到一起,作为第一个形参的值,之后,再将剩下的实参按照给出的顺序赋给其他的形参,就和我们输出的结果一样。

转载于:https://www.cnblogs.com/yufecheng/p/11302777.html

groovy常用语法及实战相关推荐

  1. SQL Server数据库学习总结及T-SQL语法使用实战

    SQL Server数据库及T-SQL实战 声明 名词解释 SQL Server数据库 安装sql server 数据库中的三种完整性 SQL Server数据库基本操作 创建数据库 指定多个数据库文 ...

  2. C语言代码示范与讲解+C语言编程规范及基础语法+编程实战

    上一篇文章:C语言程序设计概述+C语言简介+算法概述 C语言代码示范与讲解+C语言编程规范及基础语法+编程实战 一:代码示范集加讲解 1.C语言第一个代码:打印"This is the fi ...

  3. R语言switch语句语法、实战:Switch语句用来处理嵌套的if else处理起来比较困难或者麻烦的条件判断问题

    R语言switch语句语法.实战:Switch语句用来处理嵌套的if else处理起来比较困难或者麻烦的条件判断问题 目录

  4. Markdown通用的常用语法说明

    前言 Markdown 是一种轻量级的 标记语言,语法简洁明了.学习容易,还具有其他很多优点,目前被越来越多的人用来写作使用. Markdown具有一系列衍生版本,用于扩展Markdown的功能(如表 ...

  5. jsp 4种常用语法3个编译指令7个动作指令

    4种常用语法: 注释:<%--注释--%> 声明:<%!声明部分%> 输出:<%=%> 脚本:可以包含任何java可执行代码.例 <% for(int i=0 ...

  6. [转]C++/CLI与C#常用语法对比

    [转]C++/CLI与C#常用语法对比 Kenny Kerr 一篇名为C++: The Most Powerful Language for .NET Framework Programming文章中 ...

  7. 每天学一点儿shell:Shell的常用语法规则

    文章目录 Shell 参数传递 Shell 数组 Shell 基本运算符 算数运算符 关系运算符 布尔运算符 逻辑运算符 字符串运算符(重点) 文件测试运算符 Shell 常用语法 Shell 函数 ...

  8. 【shell】常用语法 -b file -c file -f file-d file -x file

    [shell]常用语法 -b file  -c file  -f file-d file  -x file      一.test条件判断 1,test文件测试: -b file     若文件存在且 ...

  9. Go Time常用语法

    Go Time常用语法 目录 获取当前时间戳和string类型的格式化时间 构造指定时间 时间戳和格式化时间相互转换 获取当前几月,几号,星期几 待续,用到什么补充什么 1. 获取当前时间戳和stri ...

  10. Mysql常用语法总结

    Mysql常用语法总结如下: #连接mysql数据库(Dos下面) mysql -u root -p 123 #创建数据库 create database myschool; #创建表 drop ta ...

最新文章

  1. SIM300实现GPRS上网
  2. JavaSE 6之脚本引擎让程序如虎添翼
  3. 吐血整理!近二十年全国数学联赛赛题大全,烧脑全集来啦!
  4. 代码流星雨是什么形式_为什么要在2020年与流星合作
  5. html5教学文档笔记,4.HTML 教程- (HTML5 基础)
  6. 看几个源码,自己多做项目了!
  7. 实现有意识自主学习的智能程序(1)
  8. 微课|中学生可以这样学Python(6.5节):lambda表达式
  9. spring boot项目下的application.properties中的logging.level设置日志级别
  10. Gentoo下搭建DNS中转服务器基本配置
  11. imreadraw的注册
  12. android+p+华为手机,Android P六大特性曝光支持刘海屏_华为 P20_手机新闻-中关村在线...
  13. Unable to instantiate application com.honjane.app.MyApplication
  14. 肯德尔系数怎么分析_论文实战2——德尔菲法与信度分析
  15. [POI2012]SZA-Cloakroom
  16. java识别音高_如何找出音乐的音高
  17. 修改elementui 的datepicker日期选择器自然周从周一至周日
  18. 诗歌十一 十二则名门家训(非淡泊无以明志,非宁静无以致远)
  19. HBase in Practice - 性能、监控及问题解决
  20. three.js例子

热门文章

  1. 广告位管理系统---使用说明
  2. 449A - Jzzhu and Chocolate 贪心
  3. Illustrator中文版教程,如何在 Illustrator中设置图标项目?
  4. 如何从 Mac 上的“照片”中导出照片、视频和幻灯片放映?
  5. ON1 Photo RAW 2022 for Mac(ps/lr滤镜raw图像编辑器)
  6. 如何保护Mac的数据安全?
  7. 新上手的Mac怎么开始盘?
  8. Mac电脑共享“公共文件夹”以外的文件夹的设置教程
  9. .NET:OrderBy和ThenBy
  10. 找出数列中个数大于总数一半的元素(编程之美2.3)