很抱歉,如果标题很糟糕,不确定如何提出这个问题......
假设我有一些接口Foo接受参数
public interface IFoo<Bar extends IBar>{
public Bar generateBar();
}
我有另一个类,它接受一个foo对象并生成一个bar对象。我可以这样定义它。
public class FooBar<Bar extends IBar, Foo extends IFoo<Bar>>{
private Foo foo;
public FooBar(Foo foo){
this.foo = foo;
}
public Bar getBar(){
this.foo.generateBar();
}
一切正常。但是,将Bar定义为我的FooBar类的参数似乎很愚蠢。 IFoo对象将被参数化以获取Bar值,因此我假设我可以从Foo对象具有的任何参数推断Bar的类型;从而避免每次定义FooBar对象时必须提供两个参数。
有没有办法可以做到这一点?而不是使Bar成为FooBar参数化类型的一部分,只是从Foo的参数中推断它?
编辑:答案似乎是无法完成,正如已经回答的那样。但是,我打算将这个开放一天,因为我希望有人可以发布一个答案,不仅可以完成,而且为什么是不可能的。具体来说,这只是java开发人员从未选择支持的用例,或者是否有一个原因使得支持其他参数化检查的相同编译时类型检查不可能通过查看特定的IFoo类型参数来推断Bar类型。是不是可以由编译器确定IFoo参数以及任何参数化类型?
答案 0 :(得分:2)
如果你关心IFoo
的实际类型参数,那么你所拥有的是正确的 - 声明类型参数Bar
,因此当声明时它可以是IFoo
的类型参数Foo
。
但是,如果您不关心代码IFoo
的类型参数是什么,那么您可以删除Bar
类型参数并将类型参数替换为{{1}带有通配符绑定。
IFoo
您的class FooBar<Foo extends IFoo<? extends IBar>>{
方法需要返回getBar
。
IBar
答案 1 :(得分:1)
为了拥有一个创建Bar对象的方法,您需要一个Class<Bar>
类型的对象。然后你可以使用:
class FooBar ...{
Class<Bar> barClass = ...;
public Bar getBar(){
return barClass.newInstance();
}
}
有多种方法可以获得barClass。我不确定要推荐哪种设计,因为你给了我们任意类型的Foo,Bar等。
更通用的解决方案是:
class FooBar<T> ...{
Class<T> someClass = ...;
public T getInstance(){
return someClass.newInstance();
}
}
您需要以某种方式将Class<Bar>
作为参数传递。
答案 2 :(得分:0)
大概你的getBar方法会返回一个Bar。由于类型擦除,您无法推断类型。你可以返回一个裸的对象进行投射,但这相当违背了泛型的目的。
答案 3 :(得分:0)
回答我自己的问题,只是提到我在我的具体情况下使用的方法,因为我想要的工作无法完成。老实说,这很简单,所以我应该先尝试一下,但是我想知道参数化可以做些什么。
我的FooBar等价物现在看起来像这样:
public class FooBar<Bar extends IBar>{
private IFoo<Bar> foo;
public FooBar(IFoo<Bar> foo){
this.foo = foo;
}
public Bar getBar(){
this.foo.generateBar();
}