调整Groovy JavaBeans规范兼容性更改

Groovy 3更符合JavaBeans规范的一个边缘情况场景,该场景涉及名称以大写字母开头的任何字段。此更改会对属性的处理产生影响。

Groovy特性

属性的定义依据Groovy公共文档是:

属性是类的外部可见特性。Java中的典型方法是遵循JavaBeans规范中概述的约定,即使用私有支持字段和getter /setter的组合来表示属性,而不是仅仅使用公共字段来表示这些特性(这提供了更有限的抽象并限制了重构的可能性)。Groovy遵循这些相同的约定,但提供了一种更简单的方法来定义属性。

下面的代码示例将生成以下内容:

  • 一个支持private字符串名称场,getName和一个setName方法。

  • 一个支持私人int场,getAge和一个setAge方法。

类Person{字符串名称int年龄}

按照惯例,即使没有支持字段,只要有符合Java Beans规范的getter或setter, Groovy也能识别属性。

class PseudoProperties{//1。a伪属性"name" void setName(字符串名称){}String getName() {} //一个伪只读属性"age" int getAge() {42} //3a伪只写属性"groovy" void setGroovy(boolean groovy) {}} def p = new PseudoProperties() p.name = 'Foo' // uses (1) assert p.age == 42 // uses (2) p.groovy = true // uses (3)

Groovy 3突破性变化

在Groovy 3中,对以大写字母开头的属性的处理已经变得更加符合JavaBeans规范。

属性映射到访问器方法的方式已经改变。在groovy 2中,在某些场景中可以访问字段而不是访问器方法,如下所示:

Groovy 2

class A {private String X = 'fieldX' private String Prop = 'fieldProp' String getProp() {'Prop'} String getX() {'X'}} new A()。with {assert prop == ' prop ' //使用getProp()访问器assert prop == 'fieldProp' //直接使用字段assert x == ' x ' //使用getX()访问器assert x == 'fieldX' //直接使用字段}

Groovy 3

class A {private String X = 'fieldX' private String Prop = 'fieldProp' String getProp() {'Prop'} String getX() {'X'}} new A()。with {assert prop == ' prop ' //使用getProp()访问器assert prop == ' prop ' //使用getProp()访问器assert x == ' x ' //使用getX()访问器assert x == ' x ' //使用getX()访问器}

当你使用静态属性时,也会出现类似的情况:

Groovy 2

class A {private static String X = 'fieldX' private static String Prop = 'fieldProp' static String getProp() {'Prop'} static String getX() {'X'} A.with {assert Prop == 'Prop' //使用静态getProp()访问器assert Prop == 'fieldProp' //使用静态getX()访问器assert X == 'fieldX' //直接使用field}

Groovy 3

class A {private static String X = 'fieldX' private static String Prop = 'fieldProp' static String getProp() {'Prop'} static String getX() {'X'} A.with {assert Prop == 'Prop' //使用静态getProp()访问器assert Prop == 'Prop' //使用静态getX()访问器assert X == 'X' //使用静态getX()访问器assert X == 'X' //使用静态getX()访问器assert X == 'X' //使用静态getX()访问器assert X == 'X'

这种破坏性的更改不会影响未覆盖访问器方法的类。

建议

为了使现有的工作流脚本与Groovy 3兼容,我们建议使用小写的属性名,除非属性名都是大写的:

class A {private String X = 'fieldX' private String XML = 'fieldXML' String getX() {'X'} String getXML() {'XML'}} new A()。使用{assert x == ' x ' //而不是使用大写的x属性assert XML == 'XML' //在这种情况下使用XML属性是唯一的方法}