一、基本概念
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
关键字 定义,方法可以接收任意数量的参数,这些参数可以不申明类型, 如果不提供可见性修饰符,则该方法为 public
。def
也可以用来声明函数。
//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
● 没有可见性修饰符的字段默认为类的属性,会自动生成对应的setter和getter方法。
● 类不需要与它的源文件有相同的名称,但还是建议采用相同的名称。
● 所有类 都继承自 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 = [:]
三、闭包
- 闭包是一个开放的、匿名的、可以接受参数和返回值并分配给变量。
- 也可以看做是一个对象,Closure类型的对象。
- 语法就是一段使用花括号{}括起来的代码块,闭包默认存在一个隐式形参it
def 闭包变量名 = { [形参1, 形参n] -> 闭包体 } - 示例
//只有一个参数或没有参数,形参可以不写 def func1 = {
print it} func1.call("test") //多个参数则要显示定义 def func2 = {
name,age ->{
println "name:$name,age:$age"}} func2.call("test1",10)
- 三个关键变量
● this:代表定义闭包的类。只有一个闭包,并且没有嵌套闭包的情况下,this、owner、delegate指向相同。this不能修改。
● owner:代表闭包定义处的类或者对象。在闭包嵌套闭包中,owner、delegate指向离它们最近的闭包对象。this指向最近的类。owner不能修改。
● delegate:可以代表任意对象,默认情况下owner和delegate是一样的。delegate释义为委托,所以可以手动修改指向其他对象。 delegate可以修改。 - 使用场景
在函数式编程中,将闭包作为参数传递给其他方法
四、trait
Trait
具有Java Interface和抽象类的双重特征,介于java的接口和抽象类之间的,主要用来解决多重继承需求,在使用上:
● 可以定义属性,非final类型的,可以修改
● 像java-interface-default方法一样,有具体实现的方法
● 没有具体实现的方法必须用abstract
修饰为抽象方法
● 可以使用extends
、implement
来继承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_编程入门先学什么的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/croovybc/2023.html