《Groovy程序设计》读书笔记之第二部分 面向Java开发者的Groovy(下)

来源:互联网 发布:淘宝模特招聘是真的吗 编辑:程序博客网 时间:2024/06/07 06:53

本文是《Groovy程序设计》一书的读书整理笔记系列文章
Paste_Image.png

这篇文章是继 http://www.jianshu.com/p/572407860ecf 的下篇,如果没有看上篇文章的话,建议先看看上篇文章。

1、 实现接口

对于接口的实现,groovy使用as操作符进行了简化,使得使用起来变得更加简单了。可以直接通过下面的代码进行比较与java实现的差异,下面代码是可以直接copy进行运行的。

SwingSample.Groovy

frame = new JFrame(size: [200, 200], layout: new FlowLayout(), defaultCloseOperation: WindowConstants.EXIT_ON_CLOSE)button = new JButton("click")positionLabel = new JLabel("")msgLabel = new JLabel("")//这里将声明的组件添加到容器中frame.contentPane.add buttonframe.contentPane.add positionLabelframe.contentPane.add msgLabel//使用as可以对实现进行简化,这里直接将实现之后的具体操作通过as指代给具体的事件监听button.addActionListener(        { JOptionPane.showMessageDialog(frame, 'You clicked!') } as ActionListener)displayMousePosition = { positionLabel.setText("$it.x, $it.y") }frame.addMouseListener(displayMousePosition as MouseListener)frame.addMouseMotionListener(displayMousePosition as MouseMotionListener)//对于接口中的多个方法,在groovy中没有去强制实现所有的方法,我们只需要实现自己需要的就可以了,下面就是实现了对应需要的两个方法handlerFocus = [        focusGained: { msgLabel.setText("good to see you!") },        focusLost  : { msgLabel.setText("Come back soon!") }]button.addFocusListener(handlerFocus as FocusListener)//实现动态的接口实现,可以使用asTypeevents = ["WindowListener", "ComponentListener"]handler = { msgLabel.setText("$it") } //这里的it表示的是传入的参数for (event in events) {    handlerImpl = handler.asType(Class.forName("java.awt.event.${event}"))    frame."add${event}"(handlerImpl)}//简要分析//handlerImpl = handler.asType(Class.forName("java.awt.event.${event}"))// 这里相当于如下代码//handlerImpl = { msgLabel.setText("$it") } as WindowListener,当然,这里是实现WindowListener还是ComponentListener还要看传入的参数决定,因为是动态的//frame."add${event}"(handlerImpl)则相当于frame.addWindowListener(handlerImpl), 当然这里的addWindowListener也是动态的frame.show()

2、布尔求值

如果在需要布尔值的地方放一个对象引用,Groovy会检查该引用是否为null,它将null视为false,将非null视为true。

str = "hello"if(str){println("str true")}

如果判断使用的是一个集合,则会判断集合是否为空,为空的话为false,否则true。

类型与bool值对他们的特殊处理

类型 为真的条件 Boolean 值为true Collection 集合不为空 Character 值不为0 CharSequence 长度不为0 Enumeration has more elements()为true Iterator hasNext()为true Number Double值不为0 Map 该映射不为空 Matcher 至少有一个匹配项 Object[] 长度大于0 其他任何类型 引用不为null

除了groovy内建的之外,在自己的类中,还可以通过实现asBoolean()方法编写自己的boolean转换

3、对Java5特性的支持

  • 自动装箱

Groovy会根据该实例的使用方式决定将其存贮为简单类型,还是对象类型。

  • for-each

Groovy提供了使用更加便捷的for-each操作

for(xxx in xxxs){}
  • enum (本文略,后续文章进行专门比较)

  • 变长参数

Groovy支持两种形式的变长参数

def fun(int a, int ... b)def fun(int a, int[] b)

不管是基于那种方式的变长参数定义,都必须将变长参数放置在末尾参数使用。

注意:有一个需要注意的是,Groovy会将包围在方框号中的值看作是ArrayList的实例,而不是纯数组,所以如果在变长参数直接使用数组值,会抛出异常,我们需要使用as进行转换操作。

fun(1, [2,3,4,5] as int[])
  • 注解

这个跟在java中一致。

  • 泛型

Groovy编译器不会像java编译器一样执行类型检查。所以泛型在Groovy中是部分丧失的。

4、使用Groovy代码生成转换

  • 使用@Canonical

这个转换注解说白了就是对toString的简化,你可以使用注解在控制是否打印全部还是部分的属性。使用的时候是在类上加

@Canonical(excludes="age")class Person{    String name    int age}

如上代码就是对age输出进行了排除,所以打印的话,会打印name的信息。

  • @Delegate

这个功能的话,简单可以理解为,Groovy使用代码为我们做了一个委派操作,将我们的类委派给其他类,因此其他类可以直接调度该被委派类的操作。看下面代码会很清楚。

class Worker {    def work() { println 'get work.' }    def analyze() { println 'analyze.' }    def writeReport() { println 'get report written' }}class Expert {    def analyze() { println 'expert analysis.' }}class Manager {    @Delegate    Worker worker = new Worker()    @Delegate    Expert expert = new Expert()}def bernie = new Manager()bernie.analyze()bernie.work()bernie.writeReport()

我们可以看到,Manager并没有这三个方法,但是呢,作为委派者,他可以操作被委派者的方法。

  • @Immutable

这里一句话简单说明: 可以使用@Immutable注解轻松的创建轻量级的不可变对象。

  • @Lazy

使用@Lazy可以让对象的初始化推迟到真正使用的时候才进行。

Groovy不仅推出了对象的初始化,而且还将字段标记为volatile,以确保现成安全、

  • @Singleton

创建一个单例模式的类。

5、陷阱

  • Groovy的== 等价于Java的equals(),当然我们还是需要进行根据情形进行判断,而引用的判断使用is()进行判断。
  • 不要在方法实现中使用代码快

本节完,谢谢阅读。

0 0
原创粉丝点击