Groovy基础

引言:

Groovy 是一种基于 Java 平台的动态编程语言(指在运行时进行类型检查的语言。在使用动态语言编写程序时,变量的类型不需要在声明时明确指定,而是在运行时根据赋给变量的值来确定类型。动态语言在代码执行过程中会进行类型检查)。它旨在简化和增强 Java 开发,提供了更简洁的语法、闭包、动态类型等特性。Groovy 可以无缝地与 Java 代码互操作,并且可以直接使用 Java 库。下面我们来学习一下Groovy的基础

注:需要有一定的java基础哦


Groovy开发环境配置

  1. 安装Intellij IEDA开发工具:Download IntelliJ IDEA -- The Leading Java and Kotlin IDE
  2. 下载Groovy SDK开发工具:The Apache Groovy programming language - Download
  3. 将Groovy SDK开发工具下的bin文件配置到环境变量中,eg:D:\apache-groovy-sdk-4.0.24\groovy-4.0.24\bin
  4. 检查是否安装成功:groovy -version

学一门语言,第一步该干什么?

  1. 那就是HelloWorld!了

  2. Groovy中可以直接使用java库,也可以直接写java语法

  3. 例如:

    Groovy 复制代码
    HelloWorld.groovy
    
    class HelloWorld{
        public static void main(String[] args){
            System.out.println("Hello World!");
        }
    }
  4. 在Groovy中可以直接调用方法不用写类、main方法

  5. 最终版本:

    Groovy 复制代码
    System.out.println("Hello World!")
    或
    println("Hello World!")
    或
    println "Hello World!"

变量

  1. java是一种强类型语言,Groovy既是强类型语言,也是弱类型语言

    1. 强类型:在定义变量时,必须声明其类型,并且后续不能更改其类型
    2. 弱类型:在定义变量时,无需声明其类型,会自动推断出其类型,并且可以修改
  2. Groovy中使用def来定义弱类型变量,也可以省略def

    Groovy 复制代码
    在java中:
    int a = 1;
    a = "abc"; //编译错误,类型不匹配
    
    在Groovy中:
    使用java的肯定是不行的
    int a = 1;
    a = "abc";//编译错误,类型不匹配
    
    使用def
    def a = 2
    a = "groovy"
    
    省略def
    a = 2
    a = "groovy"
  3. Groovy中的基本数据类型都是以对象的形式存在的,万物皆对象

  4. 证明:

    Groovy 复制代码
    int x=1
    double y=3.14
    char ch='a'
    boolean flag=true;
    
    println x.class  //class java.lang.Integer
    println y.class  //class java.lang.Double
    println ch.class //class java.lang.Character
    println flag.class //class java.lang.Boolean
    
    
    def x=1
    def y=3.14D
    def ch='a'
    def flag=true
    
    println x.class //class java.lang.Integer
    println y.class //class java.lang.Double
    println ch.class //class java.lang.String
    println flag.class //class java.lang.Boolean
  5. 尽量使用def来定义弱类型变量,因为直接使用x = 1更像赋值操作


字符串

  1. 在 Groovy 中,字符串可以使用单引号、双引号和三引号来表示

  2. 证明:

    Groovy 复制代码
    def s1='groovy'
    def s2="groovy"
    def s3='''groovy'''
    println s1.class  //class java.lang.String
    println s2.class //class java.lang.String
    println s3.class //class java.lang.String
  3. 有什么区别呢?

  4. 单引号:用于定义普通的字符串,不支持插值,即不支持在字符串中嵌入变量或表达式,就相当于java的" "字符串

  5. 双引号:用于定义支持插值的字符串,可以在字符串中嵌入变量或表达式,使用 ${} 语法。

  6. 三引号:用于定义多行字符串,支持插值。它允许字符串跨越多行,且保持格式

    Groovy 复制代码
    def name = 'Groovy'
    def message1 = 'Hello, ${name}!'  // 单引号不支持插值
    println message1  // 输出 Hello, ${name}!
    
    def message2 = "Hello, ${name}!"
    println message2  //输出 Hello, Groovy!
    
    ========================================================
    实现下面这种效果:
    Hello, Groovy!
    Welcome to the world of Groovy.
    
    单引号:
    def nam1 = 'Groovy'
    def name2 = 'Hello,'+nam1+'\nWelcome to the world of Groovy.'
    
    双引号:
    def name = 'Groovy'
    def message = "Hello,${name}\nWelcome to the world of Groovy."
    println message
    
    三引号:输出多行字符串,保持格式
    def name = 'Groovy'
    def message = """
    Hello, ${name}!
    Welcome to the world of Groovy.
    """
    
    输出结果:
    Hello, Groovy!
    Welcome to the world of Groovy.
  7. 从例子中可以看出,三引号很灵活吧,我们需要换行时,不需要使用\n


闭包Closure

  1. 在Groovy中,闭包是一种类似于匿名函数的概念,就是一个使用花括号包围的代码块,它可以被赋值给变量或作为参数传递给其他函数,闭包的类型为Closure

  2. 基本语法:{参数列表 -> 代码块} ,其中如果没有参数时,(参数列表 ->) 可省略

  3. 无参数闭包、带参数闭包:

    Groovy 复制代码
    //无参数的闭包
    def closure1={
        println "hello groovy!"
    }
    //使用
    closure1()
    
    
    //带参数的闭包
    def closure2={String name,int age->
        println "hello ${name}:age ${age}"
    }
    //使用
    closure2("wjb",18)
  4. 如果闭包只有一个参数,可以使用隐式参数 it,而不需要显式声明参数。

    Groovy 复制代码
    def greet = {
        println "Hello, ${it}!"
    }
    
    greet("Groovy")  // 输出 Hello, Groovy!
  5. 闭包的返回值:

    Groovy 复制代码
    def closure={
        println "hello ${it}"
        return "123" //可以省略return
    }
    def result=closure("groovy")
    println "result="+result
  6. 闭包的类型是Closure,Closure实现了Runnable、Callable接口,Closure实现了call方法和run方法

    Groovy 复制代码
    public abstract class Closure<V> extends GroovyObjectSupport implements Cloneable, Runnable, GroovyCallable<V>, Serializable {}
  7. 我们可以使用call、run方法来调用我们的闭包

    Groovy 复制代码
    def closure1={
        println "hello groovy!"
    }
    closure1.run()  //hello groovy!
    closure1.call() //hello groovy!
  8. 为什么呢?

  9. 我们先来看看run方法内部干了什么:

  10. 可以看到run方法调用了call方法

  11. 所以我们来看看call方法干了什么

  12. 可以看到call方法调用了传递任意数量的参数的call方法,最后找到当前的方法doCall,并调用

  13. 难道是Closure的docall方法?不对,因为Closure内部的docall方法最终还是调用了传递任意数量的参数的call方法,那是不是我们定义的闭包中有docall方法呢?我们来看看class文件(Groovy也是在JVM上运行的,也就是说,Groovy代码会编译成字节码,然后在JVM上执行)

  14. 可以看到,我们写了一小段代码,但是class文件有很多内容,这都是Groovy编译器帮我完成的,编译器会自动帮你创建一个和文件名同名的类,把你的代码放入run方法,并在main方法中调用run

  15. 从class文件中可以看到_run_closure1继承了Closure类,所以call方法中,会调用到_run_closure1的docall方法

  16. 闭包可以作为方法的参数传递

  17. 大家可以想一下下面这段代码,是java语法还是Groovy语法呢?

    Groovy 复制代码
    int x=fab(5)
    int fab(int number){
        int result=1;
        1.upto(number,{num -> result *= num})
        return result
    }
    println x;
  18. 当然是Groovy了,因为方法内有闭包,闭包是Groovy的语法,我们要记住Groovy 可以无缝地与 Java 代码互操作,并且可以直接使用 Java 库,并且可以直接使用java的语法

  19. 这个代码中我们调用了int的api upto(用来迭代从当前数字到目标数字,类似于 Java 中的 for 循环,但更加简洁和直观。)

  20. upto方法的参数需要传递一个Closure

  21. 也可以先定义closure再传入,但是不能在fab方法外部定义,必须定义在fab方法作用域之内

    Groovy 复制代码
    int fab(int number) {
        int result = 1
        def closure = { num -> result *= num } 
        1.upto(number, closure)
        return result
    }
  22. 当方法的最后一个参数是Closure时,可以将闭包放在方法调用的括号之外

    Groovy 复制代码
    int fab(int number) {
        int result = 1
        1.upto(number){ num -> result *= num }
        return result
    }
  23. 闭包中有三个关键变量:this、owner、delegate,这些变量在闭包中用来引用不同的上下文对象

  24. 从源码中可以看出owner、delegate是Closure类的两个成员变量,并且是在构造方法中进行赋值的

  25. this 变量指向定义闭包的类(即包含闭包的类)。

    1. 代码:

      Groovy 复制代码
      class A{
          class B{
              void run(){
                  def closure = {
                      println "run:"+this //run:org.example.study_1.closure.A$B@3b74ac8
                  }
                  closure()
              }
          }
      
          void print(){
              new B().run()
              def closure = {
                  println "print:"+this //print:org.example.study_1.closure.A@7d286fb6
              }
              closure()
          }
      }
      
      new A().print()
    2. 代码解释:run方法的closure闭包是定义在B类中的,所以this指向的是B的实例;print方法的closure闭包是定义在A类中的,所以this指向的是A的实例

    3. 证明:看看对应的class文件

      1. 我们先看看A类的print方法,可以看到我们定义一个闭包,groovy编译器会为我们创建一个Closure对象,那在java中Object closure = new _print_closure1(this, this);的this是指什么?是不是指向当前这个对象--》A的实例,所以print方法的closure闭包的this指向的是A的实例,那么owner、delegate的值是不是和this相同,是相同的,大家可以测试一下

      2. 我们再来看看B类的run方法,原理是不是和上面的一样?对的

    4. 总结:this指向的是闭包外第一个类的实例

  26. owner 变量指向定义闭包的对象,可能是类或闭包。

    1. 代码:

      Groovy 复制代码
      class Example {
          void run() {
              def nestedClosure = {
                  def innerClosure = {
                      println "innerClosure owner: " + owner  //org.example.study_1.closure.Example$_run_closure1@6aa61224
                  }
                  innerClosure()
                  println "nestedClosure owner: " + owner //org.example.study_1.closure.Example@30c8681
              }
              nestedClosure()
          }
      }
      
      new Example().run()  
    2. 代码解释:owner 变量指向定义闭包的对象,先看看innerClosure闭包的owner,innerClosure闭包是定义在nestedClosure闭包内的,那么owner和nestedClosure指向同一个类的实例;那nestedClosure闭包的owner呢?它是定义在Example类内的,所以owner指向的是Example的实例

    3. 证明:看看对应的class文件

      1. 我们先看innerClosure闭包,Groovy编译器帮我们创建了对象,在java中,Object innerClosure = new _closure2(this, this.getThisObject());的this指的是哪个类的实例?是_run_closure1这个类吧;我们再来看看nestedClosure闭包,在java中,Object nestedClosure = new _run_closure1(this, this);的this指的是哪个类的实例?是Example这个类吧。

    4. 总结:如果闭包定义在类中,则owner指向的是类的实例;如果闭包外还是闭包,则owner指向的是外层闭包的实例对象

  27. delegate 变量指向代理(任意)对象,默认情况下与 owner 相同,但可以被显式更改。

    1. 代码1:默认情况下,delegate 和owner相同

      Groovy 复制代码
      class Example {
          void run() {
              def nestedClosure = {
                  def innerClosure = {
                      println "innerClosure owner: " + owner  //org.example.study_1.closure.Example$_run_closure1@6aa61224
                      println "innerClosure delegate: " + delegate  //org.example.study_1.closure.Example$_run_closure1@6aa61224
                  }
                  innerClosure()
                  println "nestedClosure owner: " + owner //org.example.study_1.closure.Example@30c8681
                  println "nestedClosure delegate: " + delegate //org.example.study_1.closure.Example@30c8681
              }
              nestedClosure()
          }
      }
      
      new Example().run()
    2. 代码解释:默认情况下,owner和delegate是相同的

    3. 证明:从构造方法中可以看出,owner直接赋值给了delegate

    4. 代码2:修改delegate

      Groovy 复制代码
      //修改默认的delegate对象
      class Person {
      }
      Person p=new Person();
      def nestClouser = {
          def innerClouser = {
              println "innerClouser:" + this  //org.example.study_1.closure.ClosureTest4@6cb6decd
              println "innerClouser:" + owner //org.example.study_1.closure.ClosureTest4$_run_closure1@40317ba2
              println "innerClouser:" + delegate //org.example.study_1.closure.Person@3c01cfa1
          }
          innerClouser.setDelegate(p) //修改delegate
          innerClouser.call()
      }
      nestClouser.call()
    5. 代码解释:修改delegate的指向为Person

    6. 证明:Closure只提供了setDelegate方法,并没有提供setOwner方法

    7. 总结:在默认情况下delegate是等于owner的,delegate可以被修改

  28. 闭包的委托策略:闭包的委托策略决定了闭包在查找属性和方法时的优先级。Groovy 提供了几种不同的委托策略,可以通过 resolveStrategy 属性来设置

  29. 委托策略,默认策略是Closure.OWNER_FIRST

    1. Closure.OWNER_FIRST,优先级:owner > delegate,闭包首先在其owner上查找属性和方法,如果找不到,则在delegate上查找

    2. Closure.DELEGATE_FIRST,优先级:delegate > owner,闭包首先在其delegate上查找属性和方法,如果找不到,则在owner上查找

    3. Closure.OWNER_ONLY,闭包仅在其owner上查找属性和方法,忽略delegate

    4. Closure.DELEGATE_ONLY,闭包仅在其delegate上查找属性和方法,忽略owner

    5. Closure.TO_SELF,闭包仅在其自身上查找属性和方法,忽略owner和delegate

  30. 代码:

    Groovy 复制代码
    class Student{
        String name
        def pretty={"My name is ${name}"}
        String toString(){
            pretty.call()
        }
    }
    def student=new Student(name: "groovy") //Groovy编译器会帮我们自动添加一个构造方法
    
    class Teacher{
        String name
    }
    def teacher=new Teacher(name:'andy')
    
    println 'pretty: '+student.toString() // My name is groovy
    println 'delegate: '+student.pretty.delegate  //delegate: com.example.Student@<hashcode>
    
    student.pretty.delegate=teacher
    println 'delegate: '+student.pretty.delegate //org.example.study_1.closure.Teacher@563e4951
    //闭包的委托策略
    student.pretty.resolveStrategy=Closure.DELEGATE_FIRST
    
    println 'pretty: '+student.toString() //pretty: My name is andy
  31. 代码解释:我们这里使用的是Closure.DELEGATE_FIRST策略,那么它就会先从delegate中查找属性和方法


Gradle中常用的数据结构

  1. List:

    1. 定义:

      Groovy 复制代码
      //使用ArrayList
      def list=new ArrayList()
      
      //使用Groovy
      def list=[1,2,3,4,5]
      println list.class //class java.util.ArrayList
    2. 常用方法:

      Groovy 复制代码
      //list大小
      println list.size()
      
      ===========添加元素===========
      //使用add方法添加元素
      list.add(6)
      //使用groovy的<<添加元素
      list<<2 
      //也可以使用+添加元素
      def plusList=list+5
      //指定下标,添加元素
      plusList.add(3,9)
      
      ===========删除元素===========
      //删除下标位置的元素
      list.remove(2) 
      //删除指定的元素
      list.removeElement(2)
      //删除符合条件的元素
      list.removeAll{
          return it%2!=0
      }
      //使用-删除元素
      println list-[2,3,4] //将所有数值为2,3,4的全部remove
      
      
      ===========查找元素===========
      //查找满足条件的第一个数据
      int result=findList.find{
          return it%2 == 0
      }
      //查找所有满足条件的数据
      def result2=findList.findAll({
          return it%2 !=0
      })
      //查找是否有满足条件的数据
      def result3=findList.any{
          return it%2 ==0
      }
      //查找是否全部满足条件
      def result4=findList.every{
          return it%2 ==0
      }
      //查找最大值与最小值
      def result5=findList.min{
          return it
      }
      def result6=findList.max{
          return it
      }
      //统计满足条件的元素个数
      int result7=findList.count{
          return it>0
      }
      
      ===========排序元素===========
      //升序
      sortList.sort()
      //降序
      sortList.reverse()
      //根据条件排序
      sortList2.sort{
          it.length()
      }
      
      ===========遍历元素===========
      def list=[1,2,3,4,5]
      //传统的for循环
      //for-in循环
      for (element in list) {
          println element
      }
      //each方法
      list.each { element ->
          println element
      }
      //eachWithIndex方法
      list.eachWithIndex { element, index ->
          println "Index $index, Value $element"
      }
      //iterator方法
      def iterator = list.iterator()
      while (iterator.hasNext()) {
          println "Iterator: ${iterator.next()}"
      }
  2. Map

    1. 定义:

      Groovy 复制代码
      //使用java
      def map = new HashMap<String,Integer>()
      
      //使用Groovy
      //定义一个<Integer,String>
      def map = [1:"one",2:"two"]
      println map.getClass() //class java.util.LinkedHashMap
      //定义一个<String,String>
      def colors=[red:'ff0000',green:'00ff00',blue:'0000ff'] //会将red转换成String
      //可以强转为HashMap
      def colors=[red:'ff0000',green:'00ff00',blue:'0000ff'] as HashMap
    2. 常用方法:

      Groovy 复制代码
      def colors=[red:'ff0000',green:'00ff00',blue:'0000ff']
      
      //使用key获取value 
      println colors['red'] 或 println colors.red
      
      
      ===========添加元素===========
      //使用put方法
      //使用.
      colors.yellow='ffff00'
      //往map中再添加一个map
      colors.map = [key1:1,key2:2]
      
      ===========移除元素===========
      //使用remove方法
      colors.remove(key)
      
      ===========遍历元素===========
      //使用each
      teachers.each { key, value ->
          println "key=${key}---value=${value}"
      }
      //带索引
      teachers.eachWithIndex{ def key,def value,int index->
          println "index=${index}---key=${key}---value=${value}"
      }
      
      
      ===========查找元素===========
      //查询符合条件的元素
      def entry=teachers.find{def teacher ->
          return teacher.value.name=='groovy'
      }
      //查询符合条件的所有元素
      def entry=teachers.findAll{def teacher ->
          return teacher.value.name=='groovy'
      }
      //查找符合条件的元素个数
      def count=teachers.count{def teacher ->
          return teacher.value.name=='groovy'
      }
      
      ===========排序元素===========
      //注意:map会返回一个新的map   list是在原来的list中进行排序
      def sort=teachers.sort{def t1,def t2 ->
          return t1.key > t2.key ? 1 : -1
      }
  3. Range

    1. 在 Groovy 中,Range 是一个非常实用和灵活的特性,可以用来表示一系列连续的值。这些值可以是数字、字符等。

    2. 定义:

      Groovy 复制代码
      //数字范围
      def numberRange = 1..5
      
      //字符范围
      def charRange = 'a'..'e'
    3. 常用方法:

      Groovy 复制代码
      def range=1..10
      //获取指定下标的元素
      println range[0]
      //是否包含某元素
      println range.contains(8)
      //使用in
      println 3 in range
      //起点
      println range.from 
      //终点
      println range.to   
      
      ===========遍历元素===========
      //使用each
      range.each {
          println it
      }
      使用for-in
      for(i in range){
          println i
      }
      
      ===========switch-case===========
      def getGrade(Number score){
          def result
          switch(score){
              case 0..<60:
                  result='不及格'
                  break;
              case 60..100:
                  result='及格'
                  break;
              default:
                  result='输入异常'
          }
          return result
      }
      println getGrade(50)
      println getGrade(80)
      println getGrade(120)

面向对象语法

  1. 在Groovy中,所有的类都实现了GroovyObject接口

  2. 在Groovy中,所有类型默认都是public

  3. 在Groovy中,万物皆对象

    Groovy 复制代码
    int x=1
    double y=3.14
    char ch='a'
    boolean flag=true;
    
    println x.class  //class java.lang.Integer
    println y.class  //class java.lang.Double
    println ch.class //class java.lang.Character
    println flag.class //class java.lang.Boolean
  4. Groovy会自动为属性提供set/get方法,并且会将属性私有化:

    Groovy 复制代码
    class Person{
        String name
        Integer age
    }
    
    
    //使用
    def person = new Person()
    person.setName('Alice')
    person.setAge(18)
    println 'name:'+ person.getName() //name:Alice
    println 'age:' + person.getAge() //age:18
    1. 证明:
  5. Groovy中特有的trait关键字,类似于接口

    1. 为什么类似于接口?

      1. 看看它的class文件就知道了
      2. 可以看到DefaultAction1最后被编译成了interface
    2. trait可以包含方法(抽象方法、具体方法、私有方法)、属性

      Groovy 复制代码
      trait DefaultAction {
          def actionName = 'trait'
          int step= 10
          abstract void eat()
      
          //void eat()  //不允许,接口中才可以 
      
          void play(){
              println 'I can play!'
          }
      
          private void test(){
              println 'test()'
          }
      }
    3. trait中的方法冲突:如果一个类实现了多个trait,并且这些trait中有同名方法,Groovy会要求类明确指定使用哪个trait的方法,或者覆盖该方法。

      Groovy 复制代码
      trait A {
          void greet() { println "Hello from A" }
      }
      
      trait B {
          void greet() { println "Hello from B" }
      }
      
      class C implements A, B {
          void greet() {
              A.super.greet()  // 明确调用A trait中的greet方法
          }
      }
      
      def c = new C()
      c.greet()  // 输出: Hello from A
    4. trait中可以有静态方法,接口没有

      Groovy 复制代码
      trait Logger {
          static void log(String message) {
              println "[LOG] $message"
          }
      }
      class LoggerTest implements Logger{
      }
      
      LoggerTest.log("wq")
      
      //Logger.log("wq") //这种是不允许的
    5. trait有构造方法和静态代码块,接口并没有

      Groovy 复制代码
      trait Initializable {
          { println "Initializing trait" }
          static {
              println 'static'
          }
      }
      
      class MyClass implements Initializable {
          MyClass() {
              println "Initializing class"
          }
      }
      
      def obj = new MyClass()
      //输出:
      static
      Initializing trait
      Initializing class
    6. trait还有一些注解,例如:@SelfType----注解用于限制trait只能被特定类型的类实现、@Delegate----注解可以将trait中的方法委托给另一个对象等等,这里就不一一介绍了

    7. 总结:trait类似于接口,功能比接口多

JSON解析

  1. 使用Gson:com.google.code.gson:gson:2.8.9

    Groovy 复制代码
    Gson gson = new Gson();
    Person p1 = new Person(name:"jack",age:18)
    String json = gson.toJson(p1)
    println "json:$json"
    Person p2 = gson.fromJson(json, Person.class); 
    String jsonOutput = gson.toJson(p2); 
    println "jsonOutput:$jsonOutput" //{"name":"jack","age":18}
  2. 使用Groovy自带的json工具:JsonOutput

    Groovy 复制代码
    //对象转成json字符串
    def list=[new Person(name:'jack',age:18),
                new Person(name:'Alice',age:18)]
    println JsonOutput.toJson(list) //[{"name":"jack","age":18},{"name":"Alice","age":18}]
    //格式化
    def json=JsonOutput.toJson(list)
    println JsonOutput.prettyPrint(json)
    
    //json字符串转成对象
    def jsonSluper=new JsonSlurper()
    def object=jsonSluper.parse("[{\"age\":18,\"name\":\"jack\"},{\"age\":18,\"name\":\"Alice\"}]".getBytes())
    println object
    
    def object2=jsonSluper.parse("[{\"abc\":\"jack\"}]".getBytes())
    println object2.abc
    
    
    
    def jsonSlurper = new JsonSlurper()
    def jsonString = '[{"name":"jack","age":18},{"name":"Alice","age":18}]'
    def jsonObject = jsonSlurper.parseText(jsonString)
    
    // 手动转换为 Person 对象
    def personList = jsonObject.collect { map ->
        new Person(name: map.name, age: map.age)
    }
    
    println personList // 输出 [Person(name: jack, age: 18), Person(name: Alice, age: 18)]

XML解析

  1. 使用Groovy自带的XmlSlurper解析xml:

    Groovy 复制代码
    final String xml='''
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.jvm_demo_20200601">
        <test>12345</test>
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <activity android:name=".MainActivity2">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    </manifest>
    '''
    
    //解析XML数据
    def xmlSluper=new XmlSlurper()
    def result=xmlSluper.parseText(xml)
    println result.@package //com.example.jvm_demo_20200601
    println result.test.text() //12345
    //读取有域名空间的节点
    result.declareNamespace('android':'http://schemas.android.com/apk/res/android')
    println result.application.@'android:allowBackup'  //true
    println result.application.activity[0].@'android:name'  //.MainActivity
    println result.application.activity[1].@'android:name'  //.MainActivity2
    
    //遍历XML节点
    result.application.activity.each{activity ->
        println activity.@'android:name'
    }
  2. 使用Groovy自带的MarkupBuilder生成xml格式数据

    Groovy 复制代码
    /**
     * 生成XML格式数据
     * <html>
     *     <title id='123',name='android'>xml生成
     *          <person></person>
     *     </title>
     *     <body name='java'>
     *         <activity id='001' class='MainActivity'>abc</activity>
     *         <activity id='002' class='SecActivity'>abc</activity>
     *     </body>
     * </html>
     */
    def sw=new StringWriter()
    def xmlBuilder=new MarkupBuilder(sw)
    xmlBuilder.html(){
        title(id:'123',name:'android','xml生成'){
            person()
        }
        body(name:'java'){
            activity(id:'001',class:'MainActivity','abc')
            activity(id:'002',class:'SecActivity','abc')
        }
    }
    println sw

文件操作

Groovy 复制代码
def file=new File("D:\\JAVA\\Study_Groovy\\test.txt")
//遍历文件
file.eachLine { line ->
    println line
}

//返回所有文本
def text=file.getText()
println text

//以List<Stirng>返回文件的每一行
def text=file.readLines()
println text.toListString()

//以java中的流的方式读取文件内容
def reader=file.withReader{reader ->
    char[] buffer=new char[100]
    reader.read(buffer)
    return buffer
}
println reader
//写入数据
file.withWriter { writer ->
    writer.write("abc")
}
相关推荐
tracyZhang1 小时前
NativeAllocationRegistry----通过绑定Java对象辅助回收native对象内存的机制
android
vv啊vv1 小时前
使用android studio 开发app笔记
android·笔记·android studio
冯浩(grow up)2 小时前
使用vs code终端访问mysql报错解决
android·数据库·mysql
_一条咸鱼_5 小时前
Android Fresco 框架工具与测试模块源码深度剖析(五)
android
QING6185 小时前
Android Jetpack Security 使用入门指南
android·安全·android jetpack
顾林海5 小时前
Jetpack LiveData 使用与原理解析
android·android jetpack
七郎的小院5 小时前
性能优化ANR系列之-BroadCastReceiver ANR原理
android·性能优化·客户端
QING6185 小时前
Android Jetpack WorkManager 详解
android·kotlin·android jetpack
今阳6 小时前
鸿蒙开发笔记-14-应用上下文Context
android·华为·harmonyos
东莞梦幻科技7 小时前
体育直播系统趣猜功能开发技术实现方案
android