Groovy

2023-02-16  本文已影响0人  Zeppelin421

Groovy是一种基于Java平台的面向对象语言。 Groovy 1.0于2007年1月2日发布,其中Groovy 2.4是当前的主要版本。 Groovy通过Apache License v 2.0发布。

基本语法

class Example {
    static void main(String[] args) {
        pringln('Hello World');
    }
}
import
import groovy.xml.MarkupBuilder
def xml = new MarkupBuilder()

Groovy 在代码中默认导入一些类库,不需要显式的导入

import java.lang.* 
import java.util.* 
import java.io.* 
import java.net.* 

import groovy.lang.* 
import groovy.util.* 

import java.math.BigInteger 
import java.math.BigDecimal
令牌

令牌可以是一个关键字,一个标识符,常量,字符串文字或符号。

注释

单行注释 - //
多行注释 - /* */
Shebang行 - 通常在UNIX系统中被认知,它容许脚本直接在命令行中运行那些你已经安装的Groovy和那些已经在PATH中可用的groovy命令。

分号

分号在 Groovy 定义多个语句之间进行区分

身份标识

标识符被用来定义变量,函数或其他用户定义的变量。标识符以字母开头,美元或下划线。他们不能以数字开头。
DEF 是在 Groovy 用来定义标识符的关键字。

关键词
as assert break case
catch class const continue
def default do else
enum extends false Finally
for goto if implements
import in instanceof interface
new pull package return
super switch this throw
throws trait true try
while

内置工具

import groovy.xml.MarkupBuilder
def xml = new MarkupBuilder();

import groovy.json.JsonSlurper
def slurper = new JsonSlurper();
def obj = jsonSlurper.parseText ''' {"Integer": 12, "fraction": 12.55, "double": 12e13}'''

import groovy.json.JsonOutput
def output = JsonOutput.toJson([name: 'John', ID: 1])

范围

范围是指定值序列的速记。范围由序列中的第一个和最后一个值表示,Range可以是包含或排除。包含范围包括从第一个到最后一个的所有值,而独占范围包括除最后一个之外的所有值。

List

def list1 = []
def list2 = [1,2,3]
list2.add(12)
println list2.size()

println list2.plus(list1)
println list2 + list1

println list2.minus(list1)

Map

映射(也称为关联数组,字典,表和散列)是对象引用的无序集合。Map集合中的元素由键值访问。 Map中使用的键可以是任何类。当插入到Map集合中时,需要两个值:键和值。

Closure

闭包是一个短的匿名代码块。它通常跨越几行代码。一个方法甚至可以将代码块作为参数。它们是匿名的。

class Example {
   static void main(String[] args) {
      def clos = {println "Hello World"};
      clos.call();
   } 
}
形式参数
def clos = {param -> println "Hello ${param}"};
clos.call("World");
隐式单参

'it' 是 Groovy 中的关键字,可以用作隐式的单个参数

def clos = {println "Hello ${it}"};
clos.call("World");
变量

闭包可以定义闭包时引用变量

class Example {     
   static void main(String[] args) {
      def str1 = "Hello";
      def clos = {param -> println "${str1} ${param}"}
      clos.call("World");
        
      // We are now changing the value of the String str1 which is referenced in the closure
      str1 = "Welcome";
      clos.call("World");
   } 
}
方法中使用闭包

闭包也可以用作方法的参数。在Groovy中,很多用于数据类型(例如列表和集合)的内置方法都有闭包作为参数类型。

class Example { 
   def static Display(clo) {
      // This time the $param parameter gets replaced by the string "Inner"         
      clo.call("Inner");
   } 
    
   static void main(String[] args) {
      def str1 = "Hello";
      def clos = { param -> println "${str1} ${param}" }
      clos.call("World");
        
      // We are now changing the value of the String str1 which is referenced in the closure
      str1 = "Welcome";
      clos.call("World");
        
      // Passing our closure to a method
      Example.Display(clos);
   } 
}
列表闭包
def list = [1, 2, 3, 4];
list.each {println it}
映射闭包
def mp = ['TopicName':'Lists','TopicName':'Maps']
mp.each {println it}
mp.each {println "${it.key} maps to : ${it.value}"}

DSL

DSL(Domain Specific Language)是针对某一领域,具有受限表达性的一种计算机程序设计语言。

当调用的方法需要参数时,Groovy 不要求使用括号,若有多个参数,那么参数之间依然使用逗号分隔;如果不需要参数,那么方法的调用必须显示的使用括号。

def add(number) { 1 + number }

//DSL调用
def res = add 1
println res

也支持级联调用方式,例如 a b c d 实际上就等于 a(b).c(d)

//定义
total = 0
def a(number) {
    total += number
    return this
}
def b(number) {
    total *= number
    return this
}

//dsl
a 2 b 3
println total

Groovy 中对属性的访问就是对 getXXX 的访问,将无参数的方法名改成 getXXX 的形式,即可实现“调用无参数的方法不需要括号”的语法

def getTotal() { println "Total" }

//DSL调用
total

MOP

MOP:元对象协议。由 Groovy 语言中的一种协议。该协议的出现为元编程提供了优雅的解决方案。而 MOP 机制的核心就是 MetaClass。

元对象编程或MOP可以用于动态调用方法,并且可以即时创建类和方法。

class Student {}

def myStudent = new Student();
myStudent.Name = "Joe";
myStudent.Display();

上述 Student 是一个空类,没有成员变量 Name 和方法 Display()。
在元对象编程中,要想上面代码仍然可以工作,那 Student 必须实现 GroovyInterceptable 接口挂钩到 Groovy 的执行过程。

缺失属性
class Student implements GroovyInterceptable { 
   protected dynamicProps=[:]
    
   void setProperty(String pName,val) {
      dynamicProps[pName] = val
   }
   
   def getProperty(String pName) {
      dynamicProps[pName]
   } 
}

Student mst = new Student();
mst.Name = "Joe";
mst.ID = 1;
        
println(mst.Name);
println(mst.ID);
缺失方法

Student 类实现了 invokeMethod 方法,无论调用的方法是否存在,都会触发 invokeMethod 方法。即使调用的方法不存在,也不会提示异常错误。

class Student implements GroovyInterceptable {
   protected dynamicProps = [:]  
   void setProperty(String pName, val) {
      dynamicProps[pName] = val
   } 
   def getProperty(String pName) {
      dynamicProps[pName]
   }
   def invokeMethod(String name, Object args) {
      return "called invokeMethod $name $args"
   }
}

Student mst = new Student();
mst.Name = "Joe";
mst.ID = 1;
println(mst.Name);
println(mst.ID);
println(mst.Display(1));

Groovy 也支持 methodMissing,此方法与 invokeMethod 的不同之处在于,只有在方法分派失败的情况下才会调用此方法,此时无法找到给定名称和给定参数的方。

class Student implements GroovyInterceptable {
   protected dynamicProps = [:]  
   void setProperty(String pName, val) {
      dynamicProps[pName] = val
   }
   def getProperty(String pName) {
      dynamicProps[pName]
   }
   def methodMissing(String name, def args) {         
      println "Missing method"
   }  
}

Student mst = new Student();
mst.Name = "Joe";
mst.ID = 1;
println(mst.Name);
println(mst.ID);
mst.Display();
Metaclass
class Example {
   static void main(String[] args) {
      Student mst = new Student();
      println mst.getName()
      mst.metaClass.setAttribute(mst, 'name', 'Mark')
      println mst.getName()
   } 
} 
class Student {
   private String name = "Joe";
   public String getName() {
      return this.name;
   } 
}
上一篇 下一篇

猜你喜欢

热点阅读