Groovy学习笔记(四):特殊注解

Groovy学习笔记(四):特殊注解,第1张

概述1.@Canonical 如果要编写的toString()方法只是简单地显示以逗号分隔的字段值,则可以使用@Canonical变换让Grooovy编译器帮来干这个活。 默认情况下,它生成的代码会包含所有字段。不过可以让它仅包含特定字段,而去掉其他字段。 @Canonicalclass Student { String firstName String lastName i 1.@Canonical

如果要编写的toString()方法只是简单地显示以逗号分隔的字段值,则可以使用@Canonical变换让Grooovy编译器帮来干这个活。

默认情况下,它生成的代码会包含所有字段。不过可以让它仅包含特定字段,而去掉其他字段。

@Canonicalclass Student {    String firstname    String lastname    int age    String address}def student = new Student(firstname: "Zhang",lastname: "Sanfeng",age: 16,address: "China")println student

输出:

Student(Zhang,Sanfeng,16,China)

不管如何,这个注解在打印Log等情况下,可堪一用。

2.@Delegate

只有当派生类是真正可替换的,而且可代替基类使用时,继承才显示出其优势。从纯粹的代码复用角度看,对于其他大部分用途,委托要优于继承。

然而在Java中我们不太愿意使用委托,因为会导致代码冗余,而且需要更多工作。Groovy使委托变得非常容易,所以我们可以做出正确的设计选择。

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

在编译时,Groovy会检查Manager类,如果该类中没有被委托类中的方法,就把这些方法从被委托类中引入进来。因此,首先它会引入Expert类中的analyze()方法。

而从Worker类中,只会把work()和writeReport()方法因为进来。这时候,因为从Expert类带来的analyze()方法已经出现在Manager类中,所以Worker类中的analyze()方法会被忽略。

对于引入的每个方法,Groovy会简单地把对该方法的调用路由给实例上的相应方法,就像这样:publicObjectanalyze(){ expert.analyze() }。委托类会对新获得的方法做出响应,在下面的输出中可以看到:

expert analysis…
get work done
get report written

因为有了@Delegate注解,Manager类是可扩展的。如果在Worker或Expert类上添加或去掉了方法,不必对Manager类做任何修改,相应的变化就会生效。只需要重新编译代码,剩下的事Groovy会处理。

3.@Immutable

不可变对象天生是线程安全的,将其字段标记为final是很好的实践选择。如果用@Immutable注解标记一个类,Groovy会将其字段标记为final的,并且额外为我们创建一些便捷方法,从而使得“做正确的事情”变得更容易了。

@Immutableclass ImmutableStudent {    String name    int age}println new ImmutableStudent("jack",24)

作为反馈,Groovy给我们提供了一个构造器,其参数以类中字段定义的顺序依次列出。在构造时间过后,字段就无法修改了。此外,Groovy还添加了hashCode()、equals()和toString()方法。

运行所提供的构造器和toString()方法:

ImmutableStudent(jack,24)

可以使用@Immutable注解轻松地创建轻量级的不可变值对象。在基于Actor模型的并发应用中,线程安全是个大问题,而这些不可变值对象是作为消息传递的理想实例。

4.@Lazy

我们想把耗时对象的构建推迟到真正需要时。完全可以懒惰与高效并得,编写更少的代码,同时又能获得惰性初始化的所有好处。

下面的例子将推迟创建Heavy实例,直到真正需要它时。既可以在声明的地方直接初始化实例,也可以将创建逻辑包在一个闭包中。

class Heavy {    def size = 10    Heavy() { println "Creating Heavy : Size = $size"  }}class AsNeed {    def value    @Lazy  Heavy heavy1 = new Heavy()    @Lazy  Heavy heavy2 = {  new Heavy(size: value)  }()    AsNeed() { println 'Created AsNeed' }}def need = new AsNeed(value: 1000)println need.heavy1.sizeprintln need.heavy1.sizeprintln need.heavy2.size

Groovy不仅推迟了创建,还将字段标记为volatile,并确保创建期间是线程安全的。实例会在第一次访问这些字段的时候被创建,在输出中可以看到:

Created AsNeed
Creating Heavy : Size = 10
10
10
Creating Heavy : Size = 10
1000

另一个好处是,@Lazy注解提供了一种轻松实现线程安全的虚拟代理模式(virtual proxy pattern)的方式。

5.@Newify

在Groovy中,经常会按照传统的Java语法,使用new来创建实例。然而,在创建DSL时,去掉这个关键字,表达会更流畅。

@Newify注解可以帮助创建类似Ruby的构造器,在这里,new是该类的一个方法。该注解还可以用来创建类似Python的构造器(也类似Scala的applicator),这里可以完全去掉new。要创建类似Python的构造器,必须向@Newify注解指明类型列表。

只有将auto=false这个值作为一个参数设置给@Newify,Groovy才会创建Ruby风格的构造器。可以在不同的作用域中使用@Newify注解,比如类或方法,如下面例子所示:

@Newify(value = [Student,ImmutableStudent])def fluentCreate() {    println Student.new(firstname: "Zhang",age: 24,address: "China")    println ImmutableStudent.new("liHua",29)}fluentCreate()

结果:

Student(Zhang,24,China)
ImmutableStudent(liHua,29)

在创建DSL时,@Newify注解非常有用,它可以使得实例创建更像是一个隐式 *** 作。

6.@Singleton

要实现单件模式,正常来讲,我们会创建一个静态字段,并创建一个静态方法来初始化该字段,然后返回单件实例。我们必须确保该方法是线程安全的,同时还要决定是否要惰性创建该单件。

而通过使用@Singleton变换则完全可以避免这种麻烦,如下面例子所示:

@Singleton(lazy = true,strict = false)class PresIDent {    private PresIDent() {        println 'Instance'    }    def hello() {        println 'hello'    }}PresIDent.instance.hello()PresIDent.instance.hello()

输出:

Instance
hello
hello

这里使用@Singleton注解标记了TheUnique类,以生成静态的getInstance()方法。因为此处将lazy属性的值设为了true,所以会将实例的创建延迟到请求时。

Groovy不仅将实例创建延迟到了最后责任时刻,还保证创建部分是线程安全的。

总结

以上是内存溢出为你收集整理的Groovy学习笔记(四):特殊注解全部内容,希望文章能够帮你解决Groovy学习笔记(四):特殊注解所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1249398.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存