有一个我使用很多的库/框架有这样的方法:
public IModel<?> getDefaultModel() { /* implementation here */ }
使用此方法很好,但有时我想调用container.getDefaultModel().getObject().foo()
。但是,因为getDefaultModel()
返回IModel<?>
,这意味着getObject()
会返回Object
。
所以我被迫使用:
((Bar)container.getDefaultModel().getObject()).foo()
或
((IModel<Bar>)container.getDefaultModel()).getObject().foo()
但是如果方法是这样指定的:
public <M> IModel<M> getDefaultModel() { /* implementation here */ }
然后我可以使用:container.<Bar>getDefaultModel().getObject().foo()
我个人认为这是一种更好/更清晰的语法。
框架编写者是非常聪明的人,所以我很好奇,除了演员语法之外,两个不同的定义有什么区别?
虽然我们正在谈论这个问题,但如果这应该是一个单独的问题,请告诉我。 由于Generics代码使用编译时检查而不是运行时强制转换,它是否会生成稍快的运行时代码,然后是显式的强制转换版本?
答案 0 :(得分:4)
没有其他差异。区别在于语法。使用IModel<?>
时,必须明确地进行转换(如您所述)。但是,通过使用泛型,您可以告诉编译器在从Bar
方法返回时将其强制转换为getObject()
,因此您不必自己进行投射。除此之外,两种情况都会发生完全相同的事情。
答案 1 :(得分:0)
对于Java版本1.7及更早版本,我想,当你在链式方法调用中使用泛型类型时,编译器无法推断出类型(container.getDefaultModel()。getObject())。foo())。所以你必须明确地施展它。但是如果您使用的是Java 8,我认为您不再需要进行投射。 container.getDefaultModel().getObject()).foo()
可以使用。
阅读此http://openjdk.java.net/jeps/101和此http://blog.jooq.org/2013/11/25/a-lesser-known-java-8-feature-generalized-target-type-inference/