00、故事的起源

“二哥,听说上一篇《多线程》被 CSDN 创始人蒋涛点赞了?”三妹对她提议的《教妹学 Java》专栏一直很关心。

“嗯,有点激动。刚开始还以为是个马甲,没想到是真人!”

“其实蒋涛点赞的文章很多很多了,二哥的只是其中一篇而已。”三妹出乎意料地泼起了冷水。

“你说得没错。但这的确给我注入了新的能量,蒋涛毕竟是业界的大佬啊。”

“那就让我们开始新的篇章吧!我继续来提问,二哥你继续回答。”三妹已经迫不及待了。

01、二哥,什么是 Groovy 啊?

三妹啊,听哥来给你慢慢讲啊。

Groovy 是一种面向对象的动态类型语言,跟 Java 一样,可以运行在 JVM 上。

之所以称 Groovy 为“动态”类型语言,是因为 Groovy 的语法源于 Smalltalk 和 Ruby,提供了比 Java 更简单、更灵活的语法,可以在运行时动态地进行类型检查。

Java 语言是一种固定类型语言,比如说整形变量 int a = 0;,字符串变量 String s = "Wanger"。但在 Groovy 中,不必指定变量的类型(可选的),变量的类型是在声明(或返回)的时候确定的。

比如说可以把一个整形赋值给变量 a,然后紧接着把一个字符串赋值给变量 a。

a = 0;
a = "Wanger";

a 虽然没有指定类型,但 a 在被赋值为 0 的时候为整形,被赋值为 “Wanger” 的时候为字符串类型。

Groovy 代码能够完美地兼容 Java 代码,可以用来作为 Java 的一种补充。你甚至可以用 Groovy 在 Java 平台上进行 Java 编程,使用方式基本上和使用 Java 代码的方式相同。

许多 Java 开发人员非常喜欢 Groovy 代码和 Java 代码的相似性。因为从学习的角度看,如果知道如何编写 Java 代码,那么也就知道如何编写 Groovy 代码。

Groovy 之所以能够获得 Java 开发者的青睐,最主要原因在于完成同样的任务所需的 Groovy 代码比 Java 代码更少,因为 Groovy 具有松散的语法(允许省略分号)和一些特殊功能(比如说 JavaScript 中经常提到的闭包)。

02、二哥,能否 Hello World 一下?

三妹,Hello World 是必须的。就像你去买包包,总要先试试,再货比三家,对吧?

还记得用 Java 编写的 Hello World 吗?

public class Wanger {
    public static void main(String [] args) {
        System.out.println("Hello World");
    }
}

然后我们编译它:

javac Wanger.java

再然后我们运行已经编译好的类:

java Wanger

不出意外的话,你会在屏幕上看到“Hello World”。

那如果用 Groovy 来编写 Hello World 呢?

println "Hello World"

嗨,有没有被惊讶到了呢?

1)Groovy 松散的语法让我们不需要为打印 “Hello World” 这样的简单操作定义类。

2)Groovy 会非常聪明地为我们在 println 前面加上 System.out。

3)main 方法也不需要了。

假设代码保存在 Wanger.groovy 文件中,可以跳过编译阶段直接运行:

groovy Wanger.groovy

为什么连编译也不需要呢?因为 Groovy 属于脚本语言,可以在运行时进行解释。当然了,你也可以按照编译再运行的步骤来:

groovyc Wanger.groovy
groovy Wanger

用 groovyc 编译的 Groovy 代码会产生标准的 Java 字节码,然后也可以通过 java 命令运行生成的字节码。

注意,在命令行中运行 Groovy 代码的前提是,你需要先到 Groovy 的官网下载免安装包,再将其解压后配置到环境变量中,就像当初你配置 Java 环境变量那样。

下载地址如下:

https://groovy.apache.org/download.html

03、二哥,怎么安装 Groovy 啊?

三妹啊,由于哥一直使用 Eclipse 作为集成开发环境,所以这次的安装就以 Eclipse 的 Groovy 插件为例。

第一步,打开 Eclipse,在 Help 菜单中选择 Eclipse Marketplace,搜索 groovy 关键字,结果如下图所示。

第二步,点击 install 按钮,在功能选择对话框中勾选全部,然后点击 Confirm 按钮。

第三步,在许可证确认对话框中勾选 I accept the terms of the license agreement,点击 Finish 按钮。

第四步,安装成功后,重启 Eclipse。这时候,就可以创建一个 Groovy 的项目了,如下图所示。

第五步,创建一个 Groovy 的测试类,勾选 static void main(args) 选项,如下图所示。

生成的代码如下:

package groovyTest

class Wanger {

    static void main(args) {

    }
}

这和之前 Java 版的 HelloWorld 惊人地相似,但没有 public 修饰符,并且 main 方法的参数没有类型。

这时候,我们在 main 方法内加入 println "Hello World"

package groovyTest

class Wanger {

    static void main(args) {
        println "Hello World"
    }
}

我们可以直接选择 Run As Java Application 来运行 Groovy 代码,因为 Groovy 实际上就是 Java,只不过语法有所不同,多数情况下会短一些,但 Groovy 代码 100% 符合 Java 字节码的标准。

04、二哥,Groovy 有哪些 Java 不具备的特性呢?

三妹啊,你这个问题就问得很到位啊。

大多数情况下,Java 开发者更希望利用 Groovy 的特性来替代一些 Java 中不够优雅的解决方案。

像 Groovy 中一些可以省略的语法,比如说:

  • 语句结束处的分号;
  • 返回语句的 return 关键字;
  • 方法参数两边的括号;
  • public 访问限定符;
  • ……

这些并不是 Java 开发者要学习 Groovy 这门新语言的动力,那是什么呢?

1)Groovy List

在 Java 中,List 的操作方法大致如下:

List<String> list = new ArrayList<>();
list.add("沉默");
list.add("王二"); for (String s : list) {
    System.out.println(s);
}

但在 Groovy 中,操作方法变得更加便捷了。

可以像定义数组一样定义 list,就像下面这样:

def list = ["沉默", "王二"];

向 list 中添加元素也变得多种多样:

list.add("勇士");
list << "猛龙";
list[4] = "火箭";

也可以像数组一样取出元素:

def wanger = list[1];

2)Groovy Map

在 Java 中,Map 的操作方法大致如下:

Map<String, String> map = new HashMap<>();
map.put("name", "沉默王二");

但在 Groovy 中,操作方法变得更加便捷了。

可以按照以下方法定义一个 Map:

def map = [name:"沉默王二", "age":18];

注意:Groovy 中的键不必是字符串(可以不带双引号)。

向 map 中添加元素也变得多种多样:

map.put("money", 10000000);
map.sex = "保密";
map["work"] = "自由职业";

取出元素可以使用 . 或者 []

map.money;
map["work"]

3)Groovy 闭包

JavaScript 开发者一定不会对下面这句话感到陌生:

当一个函数被创建并传递或从另一个函数返回时,它会携带一个背包,背包中是函数声明时作用域内的所有变量。

这句话里面的“背包”就对闭包的一个恰当的比喻。Groovy 的官网是这样描述闭包的:

A closure in Groovy is an open, anonymous, block of code that can take arguments, return a value and be assigned to a variable.

大致的意思就是说,Groovy 闭包是一个开放的、匿名的代码块,可以接受参数,并把返回值赋值给变量。

闭包的定义方式如下:

{ [closureParameters -> ] statements }

其中 [closureParameters] 是以逗号分隔的参数列表,statements 是 0 个或者多个 Groovy 语句。 -> 操作符用于将参数列表与 Groovy 语句隔开。

我们来用闭包遍历一下列表,方式如下:

list.each({ x -> println x});

其中 { x -> println x} 就是一个闭包,把它作为 each() 方法的参数就可以将 list 中的元素取出,并且打印出来。

另外,闭包还有一个默认参数 it,它不需要像 x 一样声明出来,于是遍历 list 的代码就变成了下面这样:

list.each({println it});

接下来,我们再来看一下遍历 map 的方法,就是像变魔法一样。

可以使用默认的 it 作为元素,it.key 为键,it.value 为值。

map.each { println it.key + it.value }

注意: each() 方法的 () 还可以省略。

还可以自定义变量 item 作为元素,item.key 为键,item.value 为值。

map.each { entry -> println entry.key + entry.value }

或者,直接使用 key 和 value。

map.each { key, val -> println  key + val }

我们来自定义一个闭包,就像下面这样:

def addX = { x ->
    return x + 1;
};

addX 是这个闭包的名字,它接受一个参数 x,返回 x + 1。然后,我们可以这样来调用闭包:

println addX(3);
println addX.call(addX(3));

闭包在 Groovy 中不仅是一个方法,也是一个对象,所以它既可以作为参数传递,也可以调用方法。

05、故事的未完待续

“二哥,Groovy 有这么多引人注目的特性,使得它成为了一门出色的可以和 Java 共用的语言。但用 Groovy 的人并不多呢?”三妹所有所思的问。

“三妹啊,这是一个好问题呢,不过答案也显而易见。下图来自于 Groovy 官网,可以看到很多大厂的名字:Google、IBM、Linkedin、SONY。”

“不过,我听说 Java 8 中出现的 Lambda 表达式也能写出和 Groovy 一样简洁灵活的代码,你能不能教教我呢?”三妹的眼睛里充满了期待。

“三妹,你竟然知道 Lambda表达式……”

教妹学 Java:动态伴侣 Groovy的更多相关文章

  1. 教妹学 Java:大有可为的集合

    00.故事的起源 “二哥,上一篇<泛型>的反响效果怎么样啊?”三妹对她提议的<教妹学 Java>专栏很是关心. “有人评论说,‘二哥你敲代码都敲出幻想了啊.’” “呵呵,这句话 ...

  2. 教妹学 Java:晦涩难懂的泛型

    00.故事的起源 “二哥,要不我上大学的时候也学习编程吧?”有一天,三妹突发奇想地问我. “你确定要做一名程序媛吗?” “我觉得女生做程序员,有着天大的优势,尤其是我这种长相甜美的.”三妹开始认真了起 ...

  3. 教妹学 Java:难以驾驭的多线程

    00.故事的起源 “二哥,上一篇<集合>的反响效果怎么样啊?”三妹对她提议的<教妹学 Java>专栏很关心. “这篇文章的浏览量要比第一篇<泛型>好得多.” “这是 ...

  4. 教妹学Java:Spring 入门篇

    你好呀,我是沉默王二,一个和黄家驹一样身高,刘德华一样颜值的程序员(管你信不信呢).从两位偶像的年纪上,你就可以断定我的码龄至少在 10 年以上,但实话实说,我一直坚信自己只有 18 岁,因为我有一颗 ...

  5. Java动态脚本Groovy,高级啊!

    前言:请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i 简介: Groovy是用于Java虚拟机的一种敏捷的动态语言,它是一种成熟的面向对象编程语言,既可以用于面向对象编程,又可以用作纯粹的脚 ...

  6. Java动态脚本Groovy读取配置文件

    前言:请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i 核心涉及: @Value:作用是通过注解将常量.配置文件中的值.其他bean的属性值注入到变量中,作为变量的初始值. @Configur ...

  7. java开发必学知识:动态代理

    目录 1. 引言 2. 代理模式及静态代理 2.1 代理模式说明 2.2 静态代理 2.3 静态代理局限性 3. 动态代理 3.1 JAVA反射机制 3.2 JDK动态代理 3.2.1 JDK动态代理 ...

  8. Java动态调用脚本语言Groovy

    Java动态调用脚本语言Groovy 2019-05-15 目录 0. pom.xml添加依赖1. 使用GroovyShell计算表达式2. 使用GroovyScriptEngine脚本引擎加载Gro ...

  9. 学Java的前景与就业,资深程序员教你怎么开始学Java!

    IT行业一直是就业的热门岗位,程序员这个职业稳定性和收入比都有着不错的前景,那么学Java的前景和就业是什么样的呢?随着入行Java的准程序员越来越多,各种学习Java的流派也层出不穷!其实在编程的世 ...

随机推荐

  1. 由随机数rand5实现随机数rand7

    rand5表示生成随机数1,2,3,4,5 rand7表示生成随机数1,2,3,4,5,6,7 要通过rand5构造rand7现在可能没有什么思路,我们先试着用rand7生成rand5 rand7生成 ...

  2. 多项式总结(STAGE 1)

    这么难的专题居然只给了这么短时间... 然而在NC的教导之下还是有一定的收获的. 必须打广告:0,1,2,3 附带一个垃圾博客:-1 按照习惯,堆砌结论而不加证明. Section1 导数: 基本形式 ...

  3. JavaScript的函数以及循环和判断

    1.什么是函数? 这个函数跟我们数学当中的函数不太一样,我们这个函数是一段定义好的代码,可以循环使用,(这样我们更方便). 2.函数的作用: 提升代码的可复用性,将一定代码进行预定义,需要的时候才触发 ...

  4. linux命令-压缩与打包

    在 Linux 中可以识别的常见压缩格式有十几种,比如".zip"" .gz"" .bz2" ".tar" " ...

  5. 【朝花夕拾】Android自定义View篇之(七)Android事件分发机制(下)滑动冲突解决方案总结

    前言 转载请声明,转自[https://www.cnblogs.com/andy-songwei/p/11072989.html],谢谢! 前面两篇文章,花了很大篇幅讲解了Android的事件分发机制 ...

  6. [JVM 相关] Java 新型垃圾回收器(Garbage First,G1)

    回顾传统垃圾回收器 HotSpot 垃圾收集器实现 Serial Collector(串型收集器) 使用场景,大多数服务器是单核CPU. 适用收集场景:1. 新生代收集(Young Generatio ...

  7. Java生鲜电商平台-缓存架构实战

    Java生鲜电商平台-缓存架构实战 说明:在Java生鲜电商中,缓存起到了非常重要的作用,目前整个项目中才用的是redis做分布式缓存. 缓存集群 缓存集群存在的问题 1.热key 缓存集群中的某个k ...

  8. 洗牌算法及 random 中 shuffle 方法和 sample 方法浅析

    对于算法书买了一本又一本却没一本读完超过 10%,Leetcode 刷题从来没坚持超过 3 天的我来说,算法能力真的是渣渣.但是,今天决定写一篇跟算法有关的文章.起因是读了吴师兄的文章<扫雷与算 ...

  9. python高级编程——进程和进程池

    python提供了一个跨平台的多进程支持——multiprocessing模块,其包含Process类来代表一个进程对象 1.Process语法结构:(注: 传参的时候一定使用关键字传参) 2.自定义 ...

  10. SAP 固定资产添加新类别

    需求:添加资产新类别(LEASE) 步骤: 1.添加 Account determination ①SPRO->Financial Accounting(New)->Asset Accou ...