专栏首页白石Groovy 使一个类不可变
原创

Groovy 使一个类不可变

创建不可变对象,创建后不能更改。 这使得不可变对象在并发和函数编程中非常有用。 要将Java类定义为不可变,我们必须将所有属性定义为readonly和private。 只有构造函数可以设置属性的值。 Groovy文档 具有适用于不可变对象的规则的完整列表。 使类不可变的Java代码很冗长,特别是因为需要重写hashCode()equals()toString()方法。

Groovy有@ Immutable转换为我们完成所有工作。 我们只需要在类定义中定义@Imputable,我们为这个类创建的任何对象都是一个不可变对象。 Groovy按照不可变对象的规则生成一个类文件。 所以所有属性都是readonly,构造函数是为了设置属性,生成hashCode()equals()toString()方法的实现,和 more

@Immutable class User {
    String username, email
    Date created = new Date()
    Collection roles
}

def first = new User(username: 'mrhaki', email: 'email@host.com', roles: ['admin', 'user'])
assert 'mrhaki' == first.username
assert 'email@host.com' == first.email
assert ['admin', 'user'] == first.roles
assert new Date().after(first.created)
try {
    // Properties are readonly.
    first.username = 'new username'
} catch (ReadOnlyPropertyException e) {
    assert 'Cannot set readonly property: username for class: User' == e.message
}
try {
    // Collections are wrapped in immutable wrapper classes, so we cannot
    // change the contents of the collection.
    first.roles << 'new role'
} catch (UnsupportedOperationException e) {
    assert true
}


def date = new Date(109, 8, 16)
def second = new User('user', 'test@host.com', date, ['user'])
assert 'user' == second.username
assert 'test@host.com' == second.email
assert ['user'] == second.roles
assert '2009/08/16' == second.created.format('yyyy/MM/dd')
assert date == second.created
assert !date.is(second.created)  // Date, Clonables and arrays are deep copied.
// toString() implementation is created.
assert 'User(user, test@host.com, Wed Sep 16 00:00:00 UTC 2009, [user])' == second.toString() 


def third = new User(username: 'user', email: 'test@host.com', created: date, roles: ['user'])
// equals() method is also generated by the annotation and is based on the
// property values.
assert third == second

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 在裸机上部署Pulsar集群 顶

    在这个图中,连接客户端需要能够使用单个URL与Pulsar集群通信。在本例中,pulsar-cluster.acme.com对所有消息处理brokers进行了抽...

    白石
  • 巧妙解决:access denied (javax.management.MBeanTrust...

    当使用Oracle的JDBC驱动连接数据库时,会出现这种错误:access denied (javax.management.MBeanTrustPermis...

    白石
  • Gradle秘籍 顶

    白石
  • 学习python第三天数据库day2

    day01回顾: 数据库: 定义:存储数据的仓库(database,简称db) 常用的数据库对象有哪些? 1).数据表(table) ***** 2)...

    hankleo
  • 国庆手撸商品管理系统(三)

    小小咸鱼YwY
  • laravel 配置路由 api和web定义的路由的区别详解

    在api.php写的路由需要加上XXX/api/路由地址,相当于在web.php的基础上加了一层api

    砸漏
  • 【搜索反馈,您说我听】腾讯云官网搜索问题等你发言

    我们重视每一个用户的搜索体验,您在使用腾讯云官网的搜索过程中遇到的问题或者建议,都可以在本文下方的评论区留言,我们会尽快解决您的问题或者对您的建议进行回复!再次...

    腾讯云文档
  • 《西虹市首富》文章相关代码分享

    如果大家从这里直接复制代码不太方便,请关注“数据森麟”公众号,在公众号后台直接回复“西红柿”或者“西虹市”,会有详细的代码和数据、包括图片地址。也欢迎大家留言,...

    数据森麟
  • Linux学习_008_Linux下的JDK和OpenJDK有什么具体的区别

    黑泽君
  • Linux下的JDK和OpenJDK有什么具体的区别

    黑泽君

扫码关注云+社区

领取腾讯云代金券