java - Groovy/Java 可以隐式转换为子类(或具有自定义隐式转换)吗?

标签 java types groovy casting

我使用的是 MongoDB,上面有 Groovy + Grails。虽然 MongoDB Java API 过于冗长,但 Groovy 在这方面提供了帮助,因为它能够像这样编写 HashMap:

def map = [foo: "bar", one: "two"]

在 MongoDB 中,对象作为 BasicDBObjects 添加到数据库中,它扩展了 HashMap,因此我可以在 Groovy 中编写如下内容:

things.save([ foo: "bar" ] as BasicDBObject)

虽然我不知道 BasicDBOBject 强制转换来自哪里(它是内置的,因为 BasicDBObject 已经继承自 HashMap?),但如果我不必每次都添加显式强制转换,那就太好了持久化一个对象。

Groovy/Java 是否有办法使父类(super class)-子类强制转换隐式,或者至少定义自定义隐式强制转换以避免在任何地方使用 as 运算符?

最佳答案

好吧,如果您使用 Groovy,为什么不进行一些元编程呢? :-)

things.metaClass.save = { Map map -> delegate.save( map as BasicDBObject ) }

这个想法很简单:我们在 things 对象上添加一个新方法,它是一个 save() 方法,用于接收 Map 并将调用重定向到 things.save(BasicDBObject) 进行相应的转换。

如果需要,您可以将此方法直接添加到事物的类中:

ThingsClass.metaClass.save = { Map map -> delegate.save( map as BasicDBObject ) }

我编写了以下脚本试图模拟您所描述的内容,我希望我做对了:

class BasicDBObject extends HashMap { }

class Mongo {
    def save(BasicDBObject obj) {
        println "saving $obj"
    }
}

def mongo = new Mongo()

// here it will fail
try {
    mongo.save uno:1, dos:2
    assert false
} catch (e) { }


mongo.metaClass.save = { Map map -> delegate.save( map as BasicDBObject ) }

// and here it succeeds ;-)
mongo.save uno:1, dos:2 

另请注意,它不需要方括号,也不需要括号。冒号泄露了 map 的东西

对于 as 方法,它是一个可以通过 .asType(Class) 重载的运算符,我相信它是有效的,因为它尝试实例化一个新的 BasicDBObject 将映射作为构造函数中的参数传递。它可以在以下链接的第 316 行附近找到:

https://github.com/groovy/groovy-core/blob/master/src/main/org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.java

关于java - Groovy/Java 可以隐式转换为子类(或具有自定义隐式转换)吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11903007/

相关文章:

java - 未找到 JPA 内连接路径且未找到属性

java - 在java中,可以在不使用数组的情况下在另一个方法的循环中调用/调用一个方法吗?

c++ - 为什么模板类中的函数声明无效?

scala - case语句中的类型推断失败

typescript - 未推断出扩展接口(interface)的通用类型

java - 使用简单的数组通过堆叠对数字进行排序?

java - 为什么仅在使用 Java HTTP 客户端时才收到 HTTP 响应状态代码 451?

groovy - jenkins 扩展参数插件 groovy 脚本

javascript - 有没有办法通过 AJAX 从客户端 JavaScript 代码调用服务器端 Groovy 对象方法?

Groovy 不在集合中