• 秒懂Groovy【仅限于Java开发者】


    0 引言

    最近发现测试同学在用groovy,感觉很好奇就看看,结果了解了一下,发现groovy可以用在Java项目中,而且不用担心兼容问题。

    JVM的上游集合程序运行原理如下所示:
    在这里插入图片描述
    随便什么语言,反正JVM只认字节码文件,只要你的程序能够编译成JVM认识的字节码文件就行了。


    后面打算在写一些Java程序的时候,适当的引进groovy,反正两者是兼容的,而且用groovy可以节省很大一部分代码量。


    1 语法特性

    1.0 输出

    Java控制台输出语法:System.out.println()
    Groovy控制台输出语法: println() 即可

    1.2 语句

    Java 在行代码结束后,或者说在每句话结束后,都需要加分号";"。但是Groovy不需要,加不加都行,groovy会自行的推断语句是否结束。

    // Java 表达方式
    public int a = 1;
    // groovy 表达方式,两种都支持,会自行推断
    public int a = 1
    public int a = 1;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    1.3 运算符

    Java所有的运算符号groovy都支持,例如加等运算 +=之类的。
    Groovy在原有Java支持的运算符上做了扩展,提供一个我特别想在Java身上看到的特性,范围。
    groovy的范围用两个点表示,例如:1…10,表示1到10的整形数字,包含1和10。
    同时范围运算符可以配合 in 关键字使用,例如 boolean a = 1 in 1…10 // true

    def ints = 1..10
    println ints // 输出:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    println 5 in ints // 输出:true
    
    • 1
    • 2
    • 3

    1.4 定义变量 & 方法

    Java所支持的方法定义,groovy全部支持。但就局部语法做了优化,使groovy更加开放。如果不知道,或者不确定方法的返回类型,可以用 def 来代替返回类型,进行方法定义。【Tip:groovy 还做了 对象 property 的扩展,但这个玩意本人认为这玩意还是少用为好。如果读者想了解这一方面的知识,请自行百度。】

    // java 方式
    //  变量
    String s1 = "123";
    
    // 方法
    public String fun1(String r1){
    	...
    }
    // groovy 方式,以下两种方式都支持,def 代表定义的意思,至于方法返回什么类型,Groovy解释器会对其进行类型推断。
    // 变量
    def s1 = "123"
    String s1 = "123"
    // 方法
    String fun1(String r1){
    	...
    }
    def fun1(String r1){
    	...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    1.5 类

    对于Java而言,所有的POJO属性默认都是**“缺省类型”**,只能同包可见。而大多Java开发工作者,都会给POJO的属性加上 private修饰符,表示该属性只能此类访问。但对于groovy开发者而言,无需加上private修饰符,因为其属性默认就是用private修饰的。


    Tip: Kotlin有个好玩的特性,就是对于类属性可以用 set 和 get 标记,等同于 Java POJO 中的 getter 和 setter 方法。

    1.6 NPE判断

    Java 对于 NPE 是深恶痛绝,Java 工作者想出了各种办法,例如 Objects.requireNonNull(obj),groovy可以用问号“❓”解决这个问题。如下:

    // java 方式
    Objects.requireNonNull(obj)
    // groovy 可以用问号代替 NPE 判断
    obj?.find {}
    
    • 1
    • 2
    • 3
    • 4

    1.7 模版字符串

     def name = "Groovy"
     def temp = "This is ${name}"
     // 使用方式就是 ${var}
     println temp // This is Groovy
     // 还可以做表达式
     def temp2 = "This Tutorial is about ${name + "123"}"
     println temp // This is Groovy123
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2 集合特性

    2.0 定义列表

    Java 通常需要用 new ArrayList<>() 这种方式去定义列表,而 groovy 定义列表就很好玩了。具体看代码:

    // 定义列表,java 可以这样定义 Lists.of(1,2,3,4)
    def ints = [1,2,3,4]
    // 添加元素,Java 可以这样添加 ints.add(5)
    ints.add(5)
    ints << 5 // 骚吧,好玩吧
    // 删除元素,Java 这样 ints.remove(4)
    ints.remove(2)
    // 读取元素,ints.get(2)
    ints.get(3)
    ints[3] // 读取最后一个元素的骚操作:ints[-1]
    // 拼接元素, Java 这样 ints.addAll(list)
    def list = [5,6,7]
    ints += list
    ints << list
    // 去除元素,Java 这样 ints.munit(list)
    def list = [1,2]
    ints -= list
    // 遍历列表,Java 这样 ints.foeEach(item -> {}) 或者 for-in
    for(def i in ints) {...}
    ints.each({it -> ...}) //这是闭包,后面会讲
    // 查元素,Java 这样 ints.stream().find(Option)
    ints.find({it -> ...}) // 返回第一个发现的元素
    ints.findAll({it -> ...}) // 返回所有符合条件的元素
    // 其它
    ints.join(",")// 用特殊字符串拼接列表,输出 "1,2,3,4"
    ints.count(4)// 计数,输出1
    ints.sort() // 排序,输出[1,2,3,4]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    3 映射特性

    Java定义映射可以用new HashMap(),Groovy定义映射就很简单,如下:

     def map = [
         "k1": "v1",
         "k2": "v2",
         "k3": "v3"
     ]
     println map // [k1:v1, k2:v2, k3:v3]
     map."k4" = "v4" // 知道名字的
     def k4 = "k4"
     map[k4] = "v4" // 不知道名字的
     println map // [k1:v1, k2:v2, k3:v3, k4:v4]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Tip: Java支持的,groovy都支持

    4 闭包

    groovy中的闭包相当于Java中的lambda,但是写法上有所差异,具体如下:

    // java 的 lambda 
    (args...) -> {}
    // groovy 中的 Closure(闭包)
    { args -> }
    
    • 1
    • 2
    • 3
    • 4

    两个都是在大括号下写的,Java的参数需要用小括号包裹(一个参数可以省略),执行体用大括号包裹。但是如果是groovy的话,其闭包都是在大括号中,对于一个参数的话,groovy可以省略不写,直接用 it 关键字代替那个默认的参数。如下:

    // java 的 lambda 对 for-each 支持
    List<String> list = ["1234","1245","23446"]
    // Java 
    list.forEach(item -> {
    	System.out.println(item);
    })
    // groovy
    list.forEach({ item ->
    	System.out.println(item);
    })
    list.forEach({
    	System.out.println(it); // it 为默认参数,等价于item
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    好了,知道怎么用就行了,多余的边写边百度呗!


    番外1:Java 与 groovy 混合开发【maven项目】

    step1: 添加 groovy 依赖

    
    <dependency>
        <groupId>org.codehaus.groovygroupId>
        <artifactId>groovyartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    tip: 不需要指定版本信息,spring boot 中部分源码也是用 groovy 开发的,本身有 groovy 的父集。

    step2: 添加 groovy 编译插件

    <plugin>
        <groupId>org.codehaus.gmavenplusgroupId>
        <artifactId>gmavenplus-pluginartifactId>
        <version>1.13.1version>
        <executions>
            <execution>
                <goals>
                    <goal>addSourcesgoal>
                    <goal>addTestSourcesgoal>
                    <goal>generateStubsgoal>
                    <goal>compilegoal>
                    <goal>generateTestStubsgoal>
                    <goal>compileTestsgoal>
                    <goal>removeStubsgoal>
                    <goal>removeTestStubsgoal>
                goals>
            execution>
        executions>
    plugin>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    tip:groovy 编译插件会和 maven 的生命周期进行绑定,而且 groovy 插件扫描的不是 Java 目录下的源代码,而是 groovy 下的源代码

    step3: 创建与 Java 同级别的源码目录

    在这里插入图片描述
    tip1: 如果是 spring boot 开发,groovy 的包应该低于启动程序(含main方法的那个类)包级别。
    在这里插入图片描述

  • 相关阅读:
    知识图谱-命名实体-关系-免费标注工具-快速打标签-Python3
    中科院自动化所:基于关系图深度强化学习的机器人多目标包围问题新算法
    Flutter之Widget生命周期
    Aruba 胖AP配置-Aruba胖AP默认密码
    Java8中的函数式接口(你知道几个?)
    基于Java毕业设计新型农村消费贷电商平台源码+系统+mysql+lw文档+部署软件
    《乔布斯传》英文原著重点词汇笔记(十五)【 chapter fourteen】
    南京邮电大学高级语言程序设计实验四(一维与二维数组实验)
    线程池实现简单案例(C语言)
    docker中odoo项目路径
  • 原文地址:https://blog.csdn.net/qq_44503987/article/details/126455294