【发布时间】:2016-09-21 00:12:26
【问题描述】:
我不知道我必须做什么才能让这段代码正常工作。似乎编译器优化了我需要的类型转换,或者这里还有其他我不明白的东西。
我有各种对象存储在实现接口Foo 的数据库中。我有一个对象bar,它包含我用来检索Foo 对象的数据。 bar 有这些方法:
Class getFooClass()
Long getFooId()
我将类和 ID 传递给具有此签名的方法,该方法委托给 hibernate,后者根据其类和 ID 检索主题:
public <T> T get(Class<T> clazz, Serializable id);
Foo 有不同的实现者,其中一些休眠对象有一个Long id,而另一些有一个Integer id。虽然这种方法可以接受,但最好还是有正确的。因此,当我尝试在具有Integer id 的对象上调用get() 时,如下所示,我可以理解地收到一个错误,抱怨我提供了Long,其中需要Integer:
get(bar.getFooClass(), bar.getFooId());
这里没有休眠问题,我只需要提供Integer 需要Integer id 和Long 需要Long id。于是我在bar、hasLongId() 中添加了一个方法,并尝试了这个:(此时你可能会认为这不是一个好的设计,但这不是我现在的问题)
get(bar.getFooClass(),
bar.hasLongId() ? bar.getFooId() : bar.getFooId().intValue());
它仍然抱怨我提供了Long。那似乎很奇怪。然后我尝试了这个:
get(bar.getFooClass(),
bar.hasLongId() ? bar.getFooId()
: new Integer(bar.getFooId().intValue()));
同样的错误!怎么会这样?所以我在调试器中单步执行,是的,它单步执行了intValue() 和Integer 构造函数,但是在get 方法中,传递的参数实际上是Long——同一个Long 对象从getFooId()返回。
我不明白发生了什么,所以我只是尝试了各种方法:
Integer intId = bar.getFooId().intValue();
get(bar.getFooClass(), bar.hasLongId() ? bar.getFooId() : intId);
// same error
和
Serializable id = bar.hasLongId() ? bar.getFooId()
: new Integer(bar.getFooId().intValue());
get(bar.getFooClass(), id);
// same error
最后:
Serializable id;
if (bar.hasLongId()) {
id = bar.getFooId();
} else {
id = bar.getFooId().intValue();
}
get(bar.getFooClass(), id);
这个有效。所以显然它与三元运算符有关。但为什么?谁能解释一下这里发生了什么?
【问题讨论】:
-
信息不足。不要解释代码,也不要总结错误信息。根据您给我们的信息,我可能会或可能无法找出问题所在,但我不会花太多时间在这上面,因为我可以告诉您,您还没有给我们任何完整的东西。
-
与你的问题无关,但是你为什么不让
getFooId()返回一个Number而不是额外的方法和类型转换? -
投票重新打开,因为另一个问题没有讨论三元表达式或装箱值。
-
同意@shmosel,最初标记为重复的问题不同。所以我重新打开了这个问题
标签: java static-typing