Java 参数化类,如何引用作为参数化类型传递的对象的参数化类型

Java 参数化类,如何引用作为参数化类型传递的对象的参数化类型,java,generics,Java,Generics,对不起,如果标题很烂,不知道该怎么问这个问题 假设我有一个接受参数的接口Foo public interface IFoo<Bar extends IBar>{ public Bar generateBar(); } 公共接口IFoo{ 公共栏生成器Bar(); } 我还有另一个类,它接受一个foo对象并生成一个bar对象。我可以这样定义它 public class FooBar<Bar extends IBar, Foo extends IFoo&

对不起,如果标题很烂,不知道该怎么问这个问题

假设我有一个接受参数的接口Foo

  public interface IFoo<Bar extends IBar>{

      public Bar generateBar();
  }
公共接口IFoo{
公共栏生成器Bar();
}
我还有另一个类,它接受一个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();
      }
公共类FooBar{
私人富福;
公共食物吧(食物){
this.foo=foo;
}
公共酒吧{
this.foo.generateBar();
}
这一切都很好。但是,对我来说,将Bar定义为FooBar类的一个参数似乎很愚蠢。IFoo对象将被参数化以获取Bar值,因此我假设我可以从Foo对象具有的任何参数推断Bar的类型;从而避免了有人每次定义一个参数时都必须提供两个参数FooBar对象

有什么方法可以做到这一点吗?不是让Bar成为FooBar参数化类型的一部分,而是从Foo的参数推断它


编辑:答案似乎是这无法完成,正如已经回答的那样。然而,我将把这个问题留到另一天再讨论,因为我希望有人能给出一个答案,不仅是如果可以完成,而且是为什么不可能。具体地说,这仅仅是java开发人员从未选择支持的用例,还是有理由这样做支持其他参数化检查的同一编译时类型检查不可能通过查看特定的IFoo类型参数来推断Bar类型。难道编译器不能确定IFoo参数以及任何参数化类型吗?

您的getBar方法可能会返回Bar。由于类型的原因,您无法推断类型擦除。您可以返回一个裸对象进行强制转换,但这会违背泛型的目的。

如果您关心
IFoo
的实际类型参数,那么您所拥有的是正确的——声明类型参数
Bar
,因此在声明
Foo
时,它可以是
IFoo
的类型参数

但是,如果您不关心代码中
IFoo
的类型参数是什么,那么您可以消除
Bar
type参数,并用通配符边界替换
IFoo
的类型参数

class FooBar<Foo extends IFoo<? extends IBar>>{

在回答我自己的问题时,只需提及我在特定情况下使用的方法,因为我想做的事情无法完成。老实说,这很简单,所以我应该先尝试一下,但我一直在想参数化能做什么

我的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();
  }
公共类FooBar{
私人IFoo foo;
公共FooBar(ifoofoo){
this.foo=foo;
}
公共酒吧{
this.foo.generateBar();
}

为了创建一个条形图对象,您需要一个
类型的对象。然后您可以使用:

class FooBar ...{
    Class<Bar> barClass = ...;

    public Bar getBar(){
         return barClass.newInstance();
    }
}
类FooBar{
类barClass=。。。;
公共酒吧{
返回barClass.newInstance();
}
}
有多种方法可以获得barClass。我不确定该推荐什么设计,因为您给了我们任意类型的Foo、Bar等

更普遍的解决办法是:

class FooBar<T> ...{
        Class<T> someClass = ...;

        public T getInstance(){
             return someClass.newInstance();
        }
    }
类FooBar{
类someClass=。。。;
公共T getInstance(){
返回someClass.newInstance();
}
}

您需要以某种方式将
Class
作为参数传递。

这是一种很好的替代方法。在许多情况下,这是一种很好的解决方法(遗憾的是,我不是我的,我真的需要知道条的类型才能使此方法有用),但这是否意味着如果不同时使用这两个参数,我就无法维护Bar类型的知识?创建第二个类型参数
Bar
,这样您就可以将类型参数的知识维护到
IFoo
。但是在编译时,我传递了一个已经参数化的Foo对象。因此,我已经承诺如果调用我的Foo.generateBar()它将返回一个bar,这在编译时是已知的。因此,我们不能在编译时从Foo的参数化推断bar吗?不,不是。我理解类型擦除,但那是在运行时。我很好奇为什么在编译时进行的参数检查不能支持这一点。请参阅我对问题的编辑。我真的很喜欢是的,这在使用站点上是非常烦人的。没有看到任何好的解决方案:)如果使用站点碰巧不需要
getBar()
,您可以使用type
FooBar
class FooBar<T> ...{
        Class<T> someClass = ...;

        public T getInstance(){
             return someClass.newInstance();
        }
    }