Groovy阅读小注

1. 安全导航操作符 ?.,只有对象引用不为空时才会分派调用。

def a
a?.isEmpty()


2. groovy不强迫捕获我们不关心的异常。

捕获所有Exception 

try{
}catch(ex){
}


3. groovy默认都是public的。


4. groovy默认提供构造器。

class Robot{
    def type, height, width
} 
robot = new Robot(type: 'arm', width: 10, height: 40)


5. groovy传参

出现键值对的形式,groovy会将所有键值对作为第一个形参(Map)的Entry,其余参数按顺序赋给剩余形参。

class Robot{
    def access(location, weight, fragile){
        print "$fragile, $weight, $location"
    }
}
robot.access(x: 30, y: 20, z:10, 5, true)
//可改变顺序
robot.access(5, true, x: 30, y: 20, z:10)

注意:使用键值对传参,最好是当参数仅有一个Map时使用;

如果一定要使用一个Map + 多个参数传递的形式,请显示声明Map类型。

class Robot{
    def access(Map location, weight, fragile){
        print "$fragile, $weight, $location"
    }
}

当实参包含的不是两个对象和一个任意键值对,代码就会报错。


6. 可选形参, 方法可以不用再写重载

def log(x, base = 10){
    Math.log(x) / Math.log(base)
}


6.1 变长传参

最后一位形参是数组形式

def receiveVarArgs(int a, int... b){}
def receiveVarArg(int a, int[] b){}

注意:Groovy将 [2, 3]看作是ArrayList的一个实例对象,因此调用时:

receiveVarArgs(1, [2, 3, 4] as int[])


可参考Groovy创建数组、列表的区别:

int[] arr = [1, 2, 3]
def arr1 = [1, 2, 3] as int[]
def arr2 = [1, 2, 3] //ArrayList类型


7. 多赋值。返回数组,被多赋值给各个变量。

等号左边变量多的,将设为null(不能默认null的,抛异常),右边值多的,将丢弃。

def splitName(fullName){
fullName.split(' ')
}
def (firstName, lastName) = splitName('James Bond')


因此可以延伸为交换变量

def a = 1
def b = 2
(a, b) = [b, a]


8. 实现接口

一接口,单方法

def diaplyMouseLocation = {positionLabel.setText("$it.x, $it.y")}
frame.addMouseListener(diaplyMouseLocation as MouseListener)


一接口,多方法

def handleFocus = [
    focusGained : {}
    focusLost : {}
]


动态实现接口, asType()作为什么的接口实现

events = ['WindowListener', 'ComponentListener']//可以是更动态的一些输入
handler = {msgLabel.setText("$it")}
for(event in events){
    handlerImpl = handler.asType(Class.forName("java.awt.event.${event}"))
    frame."add${event}"(handlerImpl)
}


9. 默认布尔处理

groovy基本都为对象,除引用对象不为空为true外,有些对象还有如下情况也为true。

Boolean 值为true
Collection 不为空
Map 映射不为空
Char 不为0
字符串 长度大于0
数字 不为0
数组 长度大于0
其他类型 不为null
自定制 通过asBoolean()方法来重写


10. forEach

for(String greet : greetings){}
for(def greet : greetings){}

不想指定类型:

for(greet in greetings){}

或者 内部迭代器 each()


10. 静态导入支持别名

import static Math.random as rand
double value = rand()


11. java的编译时注解被忽略,如Override。

12. groovy既支持动态类型,又支持泛型。泛型在执行时进行检查生效。

13. Groovy可以重载操作符,因为每个操作符都被映射到一个标准的方法。

14. 使用注解生成代码

@Canonical 标注于类上,用于生成toString():逗号分隔各属性,可排除属性

@Canonical(excludes='lastName, age')
class Person{}


@Delegate 用于引入被委托类相应的方法包装器,用于委派任务。引入的具体实例方法与顺序有关。

查找还未有的方法进行一次引入。

class Worker{
    def work(){}
    def analyze(){}
}
class Expert{
    def analyze(){}
}
class Manager{
    @Delegate Expert expert = new Expert()//引入Expert实例的analyze方法
    @Delegate Worker worker = new Worker()//引入Worker实例的work方法
}


@Immutable 标注在类上,用于便捷生成不可变值对象,即属性final。同时提供hashCode()、equals()、toString()方法。

@Immutable
class CreditCard{
    String cardNumber
    int creditLimit
}


@Lazy 标注于属性上,懒加载

class Heavy{}
class AsNeeded {
    @Lazy Heavy heavy = new Heavy()
}


@Singleton 标注于类上,实现单例模式

@Singleton(lazy = true)
class TheUnique{
}


15. == 

== 等于调用java的equals(),除非实现Comparable接口的类型,== 等于compareTo()

is()等于java的==


16. groovy匿名内部类使用可能会有问题,会将{……}实现体当做闭包。

你可能感兴趣的:(Groovy阅读小注)