当前位置:网站首页 > Groovy编程 > 正文

groovy 调用java_编程入门先学什么

一、基本概念

1. 特点:

  • 动态性:Groovy支持动态类型和动态元编程,使得代码更加灵活和易于编写。
  • 简洁性:Groovy的语法相对于Java来说更加简洁,可以用更少的代码实现相同的功能。
  • 闭包:Groovy提供了强大的闭包支持,使得函数式编程更为便捷。
def calculator = { 
    operation, a, b -> switch (operation) { 
    case "+": return a + b case "-": return a - b case "*": return a * b case "/": return a / b default: throw new IllegalArgumentException("Unknown operation") } } println calculator("+", 5, 3) 
  • 无缝集成:Groovy可以直接使用Java类和库,与Java代码无缝集成,并且可以通过Java调用Groovy代码。
  • 领域专用语言(DSL):Groovy具有强大的DSL开发能力,允许开发人员根据特定领域的需求创建简洁、可读性高的领域特定语言。

2. 编码风格

与java基本相同,文件后缀为.groovy,示例:

class Datapatch extends BaseModel { 
    String patchId Date createdAt Date updatedAt DatapatchDetails details @Override String getPK() { 
    return patchId } @Override void setPK(String pk) { 
    patchId = pk } } 

3. 环境配置

二、语法区别

1. 变量声明

groovy除了可以使用所有java语言的变量声明方式,还可以用def来声明,def声明变量不用指定类型,访问权限默认为public

def s1 = "test" def i1 = 123 def f1 = 12.1f def c1 = 'c' int a = 10 

2. 方法

使用 返回类型def关键字 定义,方法可以接收任意数量的参数,这些参数可以不申明类型, 如果不提供可见性修饰符,则该方法为 publicdef也可以用来声明函数。

//def定义方法 不声明返回类型和参数类型 def func1(name) { 
    //$占位符插值 println "$name" } //不声明返回类型,声明参数类型 def func2(int i, int b) { 
    return i + b } //返回类型声明方法,与java相同的方式 int func3(int a){ 
    return a + 1 } //可以在方法上指定默认值 def func4(word = "Hello ", name) { 
    println word + name } //调用的时候就可以不用传这个参数,如果传了就覆盖 func4("groovy")//输出 Hello groovy //省略分号,类型,return def func5(a,b,c) { 
    a,b,c //最后一行表达式的值会return } //省略 方法括号 def number = func5 a,b,c //命名参数方法,用Map作为唯一参数 def foo(Map args){ 
    println args.name } foo(name:'test',code:1) 
与java对比可省略的地方

○ 语句后面的分号
○ 调用方法的括号
○ 参数类型
○ return,方法最后一行的表达式结果默认return
○ 类、属性和方法的访问修饰符,省略默认为pblic,java省略默认是protected

3. 类

与java类似,只不过省略public修饰符
● 默认类的修饰符为public,所有class及方法都是public
● 没有可见性修饰符的字段默认为类的属性,会自动生成对应的settergetter方法。
● 类不需要与它的源文件有相同的名称,但还是建议采用相同的名称。
● 所有类 都继承自 GroovyObject

class Test{ 
    //会自动对没有访问修饰符(默认是public)生产getter、setter String name int num //创建对象方式四和五 需要声明构造方法 TestClass(name, age) { 
    this.name = name this.age = age } //静态内部类 static class StaticInnerClass{ 
    } //非静态内部类 class InnerClass { 
    } } //创建对象方式一:与java相同 Test test1 = new Test() test1.name = "测试1" //创建对象方式二:当一个类没有构造方法的时候,其默认有一个命名参数构造方法 Test test2 = new Test(name:"测试2",num:10) //创建对象方式三:with是一种特殊的用于减少重复代码的方式 Test test3 = new Test() test3.with{ 
    name = "测试3" age = 20 } //创建对象方式四:需要先有构造方法 def test4 = ["测试4",30] as Test //创建对象方式五:需要先有构造方法 Test test5 = ["测试5",40] //创建静态内部类 def staticInner = new StaticInnerClass() //创建非静态内部类 Test test = new Test() def inner = new InnerClass(test) 

4. for循环

除了支持java的foreach和for i 形式,groovy还支持for in loop形式,支持遍历范围、列表、Map、数组和字符串等多种类型

println "for in loop range" for ( i in 0..3 ) { 
    println i } println "for in loop array" for ( i in [0, 1, 2, 3] ) { 
    println i } println "for in loop map" def map = ['a':1, 'b':2, 'c':3] for ( v in map.values() ) { 
    println v } 

5. 数据类型

GString(插值字符串groovy.lang.GStrin)

groovy独有,GString是可变的,GString和String即使有相同的字面量,它们的hashCodes的值也可能不同,因此应该避免使用GString作为Map的key

//通过占位符插值的字符串是可变的,所以这种字符串类型就是GString String s1 = "123" GString string = "$s1" println(string.hashCode()) String s2 = "123" println(s2.hashCode()) String s3 = "123" println(s3.hashCode()) //输出 48727 48690 48690 //单引号字符串,原样输出不可变,不支持插值和转义 def s1 = 'Single-quoted strings' //双引号字符串,支持插值和转义 def ss = "111" def s1 = "Double-quoted strings $ss" //三引号字符串,常用于多行文本,支持插值和转义 def s1 = """Triple-quoted strings This is second line""" 
Groovy中的容器类

List:默认实现类ArrayList,可以直接使用[]声明一个lsit

//定义list //groovy方式 def list1 = [1,2,3] def list2 = [] //java方式 def list3 = new ArrayList() //取值 //java方式 println list1.get(0) //groovy方式 println list1[-1] println list1.getAt(-2) //添加值 list1 << 4 list1.leftShift(5) list1 += 6 list1.plus 7 //插入指定位置 list1[1] = 21 list1.add(1,'e') //插入另一个列表所有值 list1.addAll(1,[11,22]) //这种方式第一个值必须是list list += [1,2] + 12 + 13 + [11,22] //删除值 //删除所有值等于1的值 list1 -= 1 list1.remove 1 //遍历 list1.foreach{ 
    //it是对应当前元素的隐式参数 println it } //带索引遍历 list1.eachWithIndex { 
    it,idx-> println "value:$it,index:$idx" } //过滤使用的一些方法 find/findAll/findIndexOf/indexOf/every/any/groupBy //常用方法collect,用来转换列表元素 def numbers = [1, 2, 3, 4, 5] def squaredNumbers = numbers.collect { 
    it * it } println "Squared numbers: $squaredNumbers" // 输出 Squared numbers: [1, 4, 9, 16, 25] 

Map:直接使用[:]声明,默认的实现类为java.util.LinkedHashMap

def key = 'name' //key 就是 "key" def person = [key: '耗子尾汁'] //用括号表示传递一个变量,key='name' person = [(key): '耗子尾汁'] //生成空map def m = new HashMap() def map = [:] 

三、闭包

  1. 闭包是一个开放的、匿名的、可以接受参数和返回值并分配给变量。
  2. 也可以看做是一个对象,Closure类型的对象。
  3. 语法就是一段使用花括号{}括起来的代码块,闭包默认存在一个隐式形参it
    def 闭包变量名 = { [形参1, 形参n] -> 闭包体 }
  4. 示例
//只有一个参数或没有参数,形参可以不写 def func1 = { 
   print it} func1.call("test") //多个参数则要显示定义 def func2 = { 
   name,age ->{ 
    println "name:$name,age:$age"}} func2.call("test1",10) 
  1. 三个关键变量
    this:代表定义闭包的类。只有一个闭包,并且没有嵌套闭包的情况下,this、owner、delegate指向相同。this不能修改。
    owner:代表闭包定义处的类或者对象。在闭包嵌套闭包中,owner、delegate指向离它们最近的闭包对象。this指向最近的类。owner不能修改。
    delegate:可以代表任意对象,默认情况下owner和delegate是一样的。delegate释义为委托,所以可以手动修改指向其他对象。 delegate可以修改。
  2. 使用场景
    在函数式编程中,将闭包作为参数传递给其他方法

四、trait

Trait具有Java Interface和抽象类的双重特征,介于java的接口和抽象类之间的,主要用来解决多重继承需求,在使用上:
● 可以定义属性,非final类型的,可以修改
● 像java-interface-default方法一样,有具体实现的方法
● 没有具体实现的方法必须用abstract修饰为抽象方法
● 可以使用extendsimplement来继承trait类
● 当不同Trait定义了相同的field或者method时, 将它们同时implements的时候,后面的会覆盖前面的。比如 class A implements B,C ,那么C的field和method会覆盖B的

trait TestInterface { 
    String name abstract void method1() default String method2(){ 
    name = "cccc" return name } } //实现类 class TestInterfaceImpl implements TestInterface { 
    @Override void method1() { 
    System.out.println(this.method2()); } static void main(String[] args) { 
    TestInterface t = new TestInterfaceImpl() t.method1() } } 

五、元编程

1、概念

元编程是指在运行时创建、修改或操纵程序的能力。在代码执行过程中对程序进行自省和改变,从而实现更高级别的抽象和灵活性。

1.1 优势和用途

动态性:元编程使得在运行时创建、修改或删除类、对象、方法等成为可能。这种动态性使得我们可以根据运行时的情况来改变程序的行为,从而增强了程序的灵活性。
简化重复工作:通过使用元编程,我们可以编写更少的代码来实现相同的功能。通过动态地生成代码、修改代码或使用模板,我们可以避免冗长、重复的代码并提高开发效率。
领域特定语言(DSL):元编程使得创建领域特定语言成为可能。通过定义自己的语法和语义,我们可以为特定领域提供更易于理解和使用的接口。
框架扩展:许多开源框架都使用元编程来实现其内部机制。通过利用元编程能力,我们可以扩展这些框架的功能,满足我们特定的需求。

1.2 流程

简单来说就是运行时期的一个策略。例如调用一个对象的某一个方法,如果这个方法不存在,编译器也不会报错,而是通过一系列的查找最终确定是调用还是抛出异常,下面就是简化后的流程:
在这里插入图片描述

1.3 使用示例

现在有一个类结构如下:

package com.alvin.learn.test class TestClass { 
    String name Integer age } 
1.3.1 动态添加属性
//TestClass本来没有code属性,动态添加一个 TestClass.metaClass.code = 10 def test = new TestClass() println test.code //可以正常修改 test.code = 2 println test.code //输出 10 2 
1.3.2 动态添加方法
def test = new TestClass() //1、现在类里面没有testMethod方法,所以执行会报 找不到此方法 test.testMethod("this is args") //2、在TestClass 里面重写 invokeMethod方法 def invokeMethod(String name,Object args){ 
    println("调用了invokeMethod,name:$name,args:$args") } //3、再次执行1处的调用,会打印 //调用了invokeMethod,name:testMethod,args:[this is args] //4、在TestClass 里面重写 methodMissing方法 def methodMissing(String name,Object args){ 
    println("调用了imethodMissing,name:$name,args:$args") } //5、再次执行1处的调用,会打印 //调用了imethodMissing,name:testMethod,args:t[this is args] //6、动态创建方法 TestClass.metaClass.testMethod = { 
    println it } def test = new TestClass() test.testMethod("this is args") //打印 this is args //7、动态添加静态方法 TestClass.metaClass.static.testStaticMethod = { 
    println 'this is a new static method' } TestClass.testStaticMethod() //打印 this is a new static method 
1.3.3 全局使用

以上使用都是临时的,在别的类中使用添加的方法需要重新注入,以下使全局使用示例。

class TestManager { 
    static TestClass createTest(String name, int age) { 
    //调用不存在的方法 return TestClass.createTest(name, age) } } class ApplicationManager { 
    static void init() { 
    //设置全局 ExpandoMetaClass.enableGlobally() //创建 Person 静态方法 TestClass.metaClass.static.createTest = { 
    String name, Integer age -> return new TestClass(name: name, age: age) } } } class Main { 
    public static void main(String[] args) { 
    println '应用程序正在启动' //初始化 ApplicationManager.init() println '应用程序初始化完成' def test = TestManager.createTest("张三", 20) println test.name + "----" + test.age } } 
1.3.4 动态创建类
// 创建一个新的类 def myClass = this.class.classLoader.parseClass(""" class MyDynamicClass { String name MyDynamicClass(String name) { this.name = name } } """) // 使用MetaClass为类添加方法 MyDynamicClass.metaClass.sayHello = { 
    -> "Hello, my name is ${ 
     delegate.name}" } // 实例化对象并调用新方法 def obj = new MyDynamicClass('Groovy') println obj.sayHello() 
到此这篇groovy 调用java_编程入门先学什么的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • Groovy编程之旅:Java世界的动态新篇章_groovy import java 类2024-11-21 23:09:07
  • 编程最好的语言_十大编程语言排行榜2024-11-21 23:09:07
  • 全面解读Spring Cloud Zuul:从配置到优化的实战指南_springcloud zuul详解2024-11-21 23:09:07
  • Groovy编程风格和语言特性指南(针对Java开发人员)_groovy语言教程2024-11-21 23:09:07
  • 全屏图片