Groovy程序设计-【第一部分Groovy起步】-02-面向Java开发者的Groovy

前言:

知识点记录来源于【Groovy程序设计】一书中,本文仅作知识点记录供日后使用查询,不做教程使用。


groovy支持java语法,并且保留了java的语义,所以我们可以随心所欲的混用两种语言

1.从Java到Groovy

先看一个简单的java代码的for循环,使用groovyConsole运行一下,如下:
在这里插入图片描述
可以看出简单的循环,“无用”的java代码可真多,实际上在groovy中,去掉每一行的分号也是被允许的。

注意:这里先说明,groovy代码编写的时候不必导入所有的常用类和包,例如,使用Calendar使用可以毫无困难的引入,同时groovy自动导入下列包:java.lang、java.util、java.io和java.net 等等。还会导入java.math.BigDecimal和java.math.BigInteger两个类等,此外,还导入了groovy.lang和groovy.util这些Groovy包。

同时,在groovy中,去掉类和方法的定义也是可以的,上面的java循环使用groovy改造后如下:

 for (int i = 0; i < 3; i++) {// 注意,代码最后没有分号了哦System.out.print("ho ")}System.out.println("Merry Groovy!!!")

甚至可以更进一步,groovy理解 println()方法,因为该方法添加到了java.lang.Object中了,同时groovy还有一个使用Range对象的更为轻量级的for循环,而且groovy对括号也很“不在意”,因此最终循环代码可以如下:

for(i in 0..2) {print 'ho '
}
println 'Merry Groovy!'

比java代码更简单明了!

1.1.实现循环的方法

上面用到了for循环以及改造为range 0…2 的方法,但是groovy还提供了更多更优雅的迭代方式。

比如 upto(),这是groovy在java.lang.Integer类中添加的一个便于使用的实例方法,可用于迭代,如下:
在这里插入图片描述
在 0 上调用了 upto(),这里的0就是Integer的是一个实例,输出现实的是所选范围内的每个值,0 1 2。
代码中的 $it 代表的是,上下文中进行循环时的索引值,后续会具体说明,这里只需要知道即可。it前面的 $ 表示让print()打印该变量的值,而不是it这两个字符。

使用 uptp()方法时,可以设置范围的上限和下限,如果范围从0开始,可以使用times(),例如上面的0.uptp(2),可以改为如下:

3.times {print "$it "
}

结果会和 0.upto(2)相同的结果,0 1 2

要在循环时跳过一些值,可以使用 step()方法, 如下:
在这里插入图片描述
最后,我们再回顾从Java到Groovy中的for range循环的groovy示例,是不是也可以写成下面这样:

3.times {print "ho "}
println "Merry Groovy!"

1.2.代码中执行命令

String扩展了execute()方法,当执行的时候,groovy创建了一个扩展了java.lang.Process的类的实例,执行实例如下:

print "svn help".execute().text

调用text时,实际是在调用groovy在类Process类上添加的getText()方法,功能就是将该进程的标准输出到一个String对象中。除了svn help,还可以执行如下:

print "groovy -v".execute().text
print "ls -l".execute().text

注意:如果你是win系统,执行这些命令是不行的(linux和unix可以),明确的说需要调用cmd命令(语法也不同,例如ls需要改成dir),例如:

print "cmd /c groovy -v".execute().text

1.3.操作符?.

经常检查对象引用是否为null?groovy可以使用?.进行判断,如下:

def foo(str){// if (str != null) {str.reverse()}str?.reverse()
}
println foo('evil')
println foo(null)

操作符 ?. 只有在引用不为null的时候才会调用执行的方法或属性,运行结果如下:

live
null

1.4.异常处理

java开发中,必须强制处理编译异常,例如Thread的sleep()方法,必须处理InterruptedException异常,File的处理必须处理FileNotFoundExcetion,如下:
在这里插入图片描述

但是groovy不需要,groovy中如果不想处理异常,groovy会默认自动传递给调用者由调用者进行处理,如下:
在这里插入图片描述
没有任何异常捕获处理和抛出,由调用者处理异常,如下:
在这里插入图片描述
如上,捕获指定的异常使用catch即可,但是如果想要捕获所有的异常而不是某一个,可以如下:
在这里插入图片描述
使用catch(ex),ex前面没有任何类型,这样就可以捕获所有的异常了,但是需要注意,ex不会捕获Exception之外的Error或Throwable,如果需要,使用 catch(Throwable throwable)

2.可选形参

groovy中的可选形参必须位于方法参数列表的末尾,定义可选形参,需要在形参列表上给它赋一个值,如下,方法log()中有一个可选的base形参,如果不提供实参,groovy认为它的默认值就是10:

def log(x, base=10){...
}
// 调用log
println log(1024)
println log(1024, 10)
println log(1024, 2)

groovy还会把末尾的数组形参作为是可选的,这其实就相当于java中的可变参数,如下:

def task(name, String[] details){println "$name - $detailds"
}
// 调用
task('Call')
task('Call', '123')
task('Call', '123', '456')
task('Call', '123', '456', '789')
// 输出结果
Call - []
Call - [123]
Call - [123, 456]
Call - [123, 456, 789]

从输出结果可以看出,groovy把末尾的参数(除了name参数之外的所有剩余参数)收集起来了赋值给数组。

3.使用多赋值

向方法传递参数获取方法的返回,如果希望方法返回多个结果,这很实用,groovy可以从方法返回的多个结果一次性赋值给多个变量,我们可以让方法返回一个数组,然后左侧用多个变量逗号分割,放在圆括号中接收即可。

其实这个类似于java中的Pair<left, right>的用法,但是java中的Pair需要自己get然后赋值,groovy不需要而且更简洁,如下:

// 空格分割参数, 返回数组
def splitname(fullname){ fullname.split(' ' )}
// 左侧两个变量接收
def (firstname, lastname) = splitname('James Bond')
// 打印结果
println "$firstname - $lastname"

结果输出:

James - Bond

可以发现,你都不用创建变量firstname和lastname,直接使用接受即可。

还可以使用该特性交换变量,不用创建中间变量过度了,如下:

def name1 = "test1"
def name2 = "test2"println "name1:$name1, name2:$name2"// 交换,注意上面已经定义了name1和name2,这里直接()即可,外面无需追加def再次定义
(name1, name2) = [name2, name1]
println "交换之后:"
println "name1:$name1, name2:$name2"

结果输出:

name1:test1, name2:test2
交换之后:
name1:test2, name2:test1

注意:如果左边变量个数 和 右侧数组的个数 不一致,groovy会这样处理,左侧的多余变量置为null,右侧的多余值被丢弃。

4.实现接口

在groovy中可以把一个映射或一个代码块转化为接口,因此可以快速直线带有多个方法的接口。这里使用线程Thread的执行举例,如下:

// 模拟java创建线程并执行
new Thread(() -> {println("线程执行1");}).run();

使用groovy:

new Thread(println("线程执行2") as Runnable).run()

看到了吗,groovy不需要Runabled的方法声明(java8开始出现了lambda),也不需要匿名内部类的实例,借助 as 操作符,相当于实现了Runabled接口。

上面是一个方法的实现,如果多个方法的接口中,只打算实现其中的某些方法而不是全部(只关心自己需要的方法),其实也很简单,只需要创建一个映射,以每个方法的名字作为键,方法对应的代码块作键值,同时用 冒号(:)分割方法名和代码块即可,如下(截图):
在这里插入图片描述

5.布尔求值

groovy的布尔求值和java的不同,根据上下文,groovy会自动把表达式计算为布尔值,先看一下例子,如下:

// java代码
String str = "hello";
int value = 4;
if (str){} // 错误语法
if (value){} // 错误语法

java要求if中的表达式必须是一个布尔表达式,例如 if(obj != null) 这种,但是groovy可不是,它会尝试判断。

如果在需要布尔表达式的地方发了一个对象引用,例如 if 中,groovy会检查这个引用是否为null,null视为false,非null视为true,如下:

def str = "groovy"
if (str) { println "hi, " + str }
// 输出结果
hi, groovy

如上,groovy将str视为表达式计算布尔值。

其实上面说的根据引用对象是否为null判断布尔值也不是对的,因为如果对象不为null,表达式的结果还和对象的类型有关,例如集合List,只有集合不为null,且至少有一个元素,才会认为true,示例代码如下:

def list = [];
println "集合, 空判断: " + (list ? "true" : "false")list = null;
println "集合, null判断: " + (list ? "true" : "false")list = [1];
println "集合, 有值判断: " + (list ? "true" : "false")

输出结果如下:

集合, 空判断: false
集合, null判断: false
集合, 有值判断: true

不仅仅集合,其他一些类型也是不仅判断null,groovy如何判断的呢,如下图:
在这里插入图片描述

6.操作符重载

groovy支持操作符重载,就是每个操作都会映射到一个标准的方法。下面演示一个示例:(截图)
在这里插入图片描述通过 ++ 操作符实现了字符a到c的循环打印,该操作符映射的是String类的next()方法,还可以进一步使用range的简介循环:
在这里插入图片描述集合也有操作符,例如 << 操作符表示向集合中添加元素,相当于leftShift()方法。
在这里插入图片描述
输出结果
在这里插入图片描述

7.陷阱

groovy确实有很多不错的功能,但是同时也存在一些“陷阱”。

7.1.groovy的==等价于java的equals()

java的==和equals()本来就已经够混乱的了,groovy又再一次加剧了“悲剧”的发生。

groovy中,==操作符映射到了java的equals()方法,那么如果我们想要对比对象的引用地址是否想等(就是java中的 ==)怎么办呢,必须使用groovy中的 is()方法,如下:

 def str1 = "hello"def str2 = str1def str3 = new String("hello")def str4 = "Hello"// trueprintln "str1 == str2: ${str1 == str2}"// trueprintln "str1 == str3: ${str1 == str3}"// falseprintln "str1 == str4: ${str1 == str4}"// trueprintln "str1.is(str2): ${str1.is(str2)}"// falseprintln "str1.is(str3): ${str1.is(str3)}"// falseprintln "str1.is(str4): ${str1.is(str4)}"

实际上groovy的==并不总是映射到java的equals()方法,只有该类没有实现Comparable的时候才成立,否则groovy的==会映射到该类的compareTo()方法。
在这里插入图片描述通过输出发现,实现了Comparable接口的,==映射到了compareTo()方法,而不是equals()方法,所以,在比较对象的时候,首先确定自己想要对比的是值和引用地址,然后再确定是不是使用了正确的操作符(==还是is方法)

7.2.编译时类型检查默认关闭

groovy类型是可选的,然而groovy编译时大部分情况下不会检查完整的类型,而是在运行时遇到类型执行强制类型转换,例如:
在这里插入图片描述
这段代码可以正常编译,但是运行时就会报错,因为groovy不会检查,运行时候 hello 强制转换为int类型的时候就报错了,所以groovy把这工作留给了运行时处理。

所以groovy中的 x = y,实际上就是 x = (ClassOfX)y。类似的,如果调用了一个不存在的方法,编译也是通过的,运行时就会报错:
在这里插入图片描述为什么groovy这么做,后续会说明,其实这反而对groovy来说是一个有点哟!

7.3.新的关键字

groovy的 in ,def 都对于java来说是新的关键字,需要注意。

同时注意 it,这对groovy来说也是一个特殊的关键字。

7.4.创建基本类型的数组

groovy创建一个int数组,如下:

int[] size = [1,2,3]

定义了一个数组,如果去掉了 int[],groovy就会认为定义了一个集合:

def size = [1,2,3]

这样就是一个集合了,如果还想这么定义一个数组,就需要做出一点改变,如下:

def size = [1,2,3] as int[]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/824967.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从「宏大叙事」到「生活叙事」,小红书品牌种草的的“正确姿势”

不同于抖音和微博&#xff0c;在小红书上&#xff0c;品牌营销的基调应该是怎样的&#xff1f;品牌怎样与小红书用户对话&#xff1f;什么样的内容&#xff0c;才能走进小红书用户的心中&#xff1f;本期&#xff0c;小编将带大家洞察品牌在小红书营销的“正确姿势”。从「小美…

Table表格(关于个人介绍与图片)

展开行&#xff1a; <el-table :data"gainData" :border"gainParentBorder" style"width: 100%"><el-table-column type"expand"><template #default"props"><div m"4"><h3>工作经…

百度文心一言:官方开放API开发基础

目录 一、模型介绍 1.1主要预置模型介绍 1.2 计费单价 二、前置条件 2.1 创建应用获取 Access Key 与 Secret Key 2.2 设置Access Key 与 Secret Key 三、基于千帆SDK开发 3.1 Maven引入SDK 3.2 代码实现 3.3 运行代码 一、模型介绍 文心一言&#xff08;英文名&…

Java实现生成中间带图标的二维码

Java实现生成中间带图标的二维码 生成Base64格式的二维码&#xff0c;返回html渲染 package your.package;import com.google.zxing.*; import com.google.zxing.client.j2se.MatrixToImageWriter; import com.google.zxing.common.BitMatrix; import com.google.zxing.qrcod…

DSPE-PEG-TPP 磷脂聚乙二醇-磷酸三苯酯 靶向线粒体纳米颗粒药物递送系统

DSPE-PEG-TPP 磷脂聚乙二醇-磷酸三苯酯 靶向线粒体纳米颗粒药物递送系统 【中文名称】磷脂-聚乙二醇-磷酸三苯酯 【英文名称】DSPE-PEG-TPP 【结 构】 【品 牌】碳水科技&#xff08;Tanshtech&#xff09; 【纯 度】95%以上 【保 存】-20℃ 【规 格】50mg,…

数字工厂系统的开发

数字工厂系统&#xff08;Digital Factory System&#xff0c;DFS&#xff09;是基于数字孪生技术&#xff08;Digital Twin Technology&#xff09;和信息物理融合系统&#xff08;Cyber-Physical System&#xff0c;CPS&#xff09;构建的&#xff0c;用于仿真、分析和优化制…

密码学 | 承诺:基本概念

目录 正文 1 承诺的交互 2 承诺的属性 3 硬币抛掷问题 3.1 朴素版方案 3.2 承诺版方案 &#x1f951;源自&#xff1a;https://en.wikipedia.org/wiki/Commitment_scheme &#x1f951;写在前面&#xff1a;英文的承诺是 commitment scheme&#xff0c;否则很难进行…

网络爬虫入门

爬虫&#xff08;也被称为网络爬虫或网络蜘蛛&#xff09;是一种自动化程序&#xff0c;它可以在互联网上自动抓取数据。爬虫的基本工作原理通常包括以下几个步骤&#xff1a;发送请求&#xff1a;爬虫向目标网站发送HTTP请求&#xff0c;请求网页内容。接收响应&#xff1a;爬…

根据 Figma 设计稿自动生成 Python GUI | 开源日报 No.221

ParthJadhav/Tkinter-Designer Stars: 8.0k License: BSD-3-Clause Tkinter-Designer 是一个用于快速创建 Python GUI 的工具&#xff0c;通过使用 Figma 设计软件&#xff0c;可以轻松地生成美观的 Tkinter GUI。 主要功能和优势包括&#xff1a; 拖放界面设计比手写代码更快…

百亿补贴低价的治理思路

各大电商平台都有陆续在推出百亿补贴通道&#xff0c;这对消费者来说&#xff0c;会更便捷&#xff0c;因为平台百亿补贴价格较低&#xff0c;不需要消费者再进行多链接、多平台的比价工作&#xff0c;直接下单即可&#xff0c;由于百亿补贴链接的上架主导权在平台&#xff0c;…

​面试经典150题——从前序与中序遍历序列构造二叉树

​ 1. 题目描述 2. 题目分析与解析 二叉树的前序、中序和后序遍历 二叉树的前序、中序和后序遍历是树的三种基本遍历方式&#xff0c;它们是通过不同的顺序来访问树中的节点的。 前序遍历&#xff08;Pre-order traversal&#xff09;&#xff1a; 访问根节点 前序遍历左子树…

详细介绍医用PSA变压吸附制氧机设备的工艺特点

随着技术的不断进步&#xff0c;医用氧气作为一种重要的治疗资源&#xff0c;其供应方式也在不断地改进和升级。其中&#xff0c;医用PSA(Pressure Swing Adsorption&#xff0c;变压吸附)变压吸附制氧机设备因其高效、安全、稳定的特点&#xff0c;受到了广大机构的青睐。那么…

Java高阶私房菜:快速学会异步编程CompletableFuture

为了使主程代码不受阻塞之苦&#xff0c;一般使用异步编程&#xff0c;而异步编程架构在JDK1.5便已有了雏形&#xff0c;主要通过Future和Callable实现&#xff0c;但其操作方法十分繁琐&#xff0c;想要异步获取结果,通常要以轮询的方式去获取结果&#xff0c;具体如下&#x…

传统零售行业如何做数字化转型?

传统零售行业的数字化转型是一个系统性的过程&#xff0c;涉及到企业的多个方面。以下是一些关键步骤和策略&#xff0c;帮助传统零售企业实现数字化转型&#xff1a; 1、明确转型目标和战略 首先&#xff0c;企业需要明确数字化转型的目标和战略。包括确定企业的核心竞争力、…

照片光晕光学特效模拟调色Boris FX Optics 2024 mac下载安装教程

Boris FX Optics 2024 Mac版是一款照片光晕光学特效模拟调色软件&#xff0c;旨在模拟光学相机滤镜&#xff0c;专用镜头&#xff0c;胶卷和颗粒&#xff0c;镜头光晕&#xff0c;光学实验室处理&#xff0c;色彩校正以及自然光和摄影效果。用户可以通过应用光学并从160个滤镜和…

HAL STM32 I2C方式读取MT6701磁编码器获取角度例程

HAL STM32 I2C方式读取MT6701磁编码器获取角度例程 &#x1f4cd;相关篇《Arduino通过I2C驱动MT6701磁编码器并读取角度数据》&#x1f388;《STM32 软件I2C方式读取MT6701磁编码器获取角度例程》&#x1f4cc;MT6701当前最新文档资料&#xff1a;https://www.magntek.com.cn/u…

甘特图:项目管理者的必备神器,如何提高工作效率?

甘特图是什么&#xff1f;项目管理者大多都熟悉甘特图&#xff0c;它是一种直观展示项目计划执行过程的工具。通过条形图来显示项目、任务的时间安排&#xff0c;以及实际进度与计划进度的对比情况。 在我个人的项目管理实践中&#xff0c;甘特图确实帮助我提高了工作效率&am…

威纶通触摸屏与S7-1200进行标签通信(符号寻址)的具体方法示例

威纶通与S7-1200进行标签通信(符号寻址)的具体方法示例 前面和大家分享了威纶通与S7-1200通过绝对地址进行以太网通信的具体方法,具体内容可参考以下链接中的内容: 威纶通触摸屏与S7-1200以太网通信的具体方法和步骤(非常详细) 如下图所示,打开博途软件,新建一个项目,…

中国老铁路增开对国际旅客列车开行

4月13日&#xff0c;中老铁路国际旅客列车开行一周年之际&#xff0c;中老两国铁路部门在中国西双版纳至老挝琅勃拉邦两大著名旅游城市间增开1对国际旅客列车&#xff0c;旅客乘火车可实现两地间当日往返。标题&#xff1a;古道新程——中国老铁路增开国际旅客列车 在这个日新月…

图书管理系统概述

自友图书馆管理系统解决方案适用于中小学、大中专院校以及企事业单位中小型图书馆的自动化管理需求&#xff0c;其功能覆盖了图书馆自动化集成管理业务流程所包括的所有环节。《图书馆管理系统》首先应该按照我国图书馆行业通用CNMARC格式及《中图法第四版》行业标准开发而成,支…