这是(groovy)类的一部分,它将一些数据存储在Mongodb中:
long save(Object data) {
def customerReference = getNextCustomerReference()
def map = ['customerReference': customerReference, 'data': data, 'created': new Date()]
BasicDBObject basicDBObject = new BasicDBObject(map)
collection.insert(basicDBObject)
customerReference
}
private long getNextCustomerReference() {
1234
}
即使我已明确表示我想要一个原始的long,但最终在数据库中的是一个对象:
{ "_id" : ObjectId("52f3c0597d844b0fcee29013"), "customerReference" : NumberLong(1234), "data" : "original data", "created" : ISODate("2014-02-06T17:03:21.411Z") }
但是,如果我将私有方法的返回类型更改为def,则会发生这种情况:
{ "_id" : ObjectId("52f3c1477d84698725f50fe5"), "customerReference" : 1234, "data" : "data", "created" : ISODate("2014-02-06T17:07:19.055Z") }
我想要的行为(存储在数据库中的原语)。
有人可以解释这一点,因为它令人费解。当然,如果我不知道如何定义类型,Groovy应该尝试尊重它吗?
答案 0 :(得分:2)
Groovy几乎总是自动将原始类型自动装箱到它们的数字引用类型 - 等价:
long test_long() { 123l }
int test_int() { 123 }
def test_def() { 123 }
def test_def_long() { 123l }
long l = 42l
assert test_long().class == Long.class
assert test_int().class == Integer.class
assert test_def().class == Integer.class
assert test_def_long().class == Long.class
assert l.class === Long.class
如果删除long
返回类型,则会将对象自动装箱到java.lang.Integer
。看起来你的代码处理Integer
就像一个“原始”。
前段时间Groovy 1.8 introduced primitive type optimization,在某些情况下使用原始类型的内部回退。这在某些情况下会有所帮助,但是内部性能优化是您无法直接使用的(通过使用某些语法结构或类似的东西)。
有时你可以通过显式强制转换来强制原语,但是很有可能它会在方法调用和东西的过程中被转换为引用类型。