在Groovy中,我可以在POJO类上覆盖java风格的转换语法吗?

时间:2014-05-09 17:44:36

标签: groovy

我希望能够使用普通的java风格的隐式/显式转换而不是asType覆盖,以便用Java编写的源能够正常工作。我已经覆盖了字符串上的asType,类似于How to overload some Groovy Type conversion for avoiding try/catch of NumberFormatException?中建议的方法,如:

oldAsType = String.metaClass.getMetaMethod("asType", [Class] as Class[])
String.metaClass.asType = {Class typ ->
    if (Foo.class.isAssignableFrom(typ)) {
        Foo.myCast(delegate)
    } else {
        oldAsType.invoke(delegate,typ)
    }
}

我希望所有这些选项都有效:

// groovy
String barString
Foo foo = barString asType(Foo.class)  // asType works but
Foo foo = barString           // implicit cast fails
Foo foo = (Foo) barString     // explicit cast fails

后两个失败是因为groovy正在使用DefaultTypeTransformation.castToType,它不会尝试调用new Foo(),除非要转换的对象是一系列特殊情况之一或者是某种Collection类型。

请注意,解决方案Can I override cast operator in Groovy?无法解决问题,因为正在进行转换的代码是我无法更改的常规Java代码,至少不是源代码级别。我希望有一个秘密钩子进入转换或一种方法来覆盖静态castToType方法(在Java类中,由另一个Java类调用 - Can you use Groovy meta programming to override a private method on a Java class说不支持)...或其他一些我没有想过的聪明方法。

编辑:问题是关于使用Java风格的语法,主要是使用groovy工具来添加自动装箱方法。 Groovy将此机制称为“强制转换”,无论好坏,请参阅上面引用的DefaultTypeTransformation.castToType。特别是,我已经用资源类替换了枚举,并希望保留JSON序列化。 Groovy的JSON包自动将实例成员的枚举值枚举到字符串中,并且我试图使替换类与源代码的最小更改兼容地进行序列化。

2 个答案:

答案 0 :(得分:0)

这里的一部分问题是你将转换与转换混淆。使用" as"操作员与施加演员不是一回事。它们看似相似,但它们有不同的用途。

Foo foo = (Foo) barString 

没有说"用barString创建一个Foo"。这表示"声明一个名为foo的引用,将静态类型Foo与该引用相关联,然后将该引用指向引用barString当前指向的堆上的对象。"。与C ++之类的语言不同,Groovy和Java不允许您处于这样的情况:引用指向对象的类型与引用类型不兼容的情况。如果您遇到Foo引用指向堆上的String的情况,那将代表JVM中的错误。它无法完成。你可以想出用String对象创建Foo对象的方法,但这不是上面代码的内容。

答案 1 :(得分:0)

答案似乎是“否”。无需重写DefaultTypeTransformation.castToType即可进行这种元编程,这意味着要使用另一种实现策略或使用另一种语言。