我使用的是 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 行附近找到:
关于java - Groovy/Java 可以隐式转换为子类(或具有自定义隐式转换)吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11903007/