简体   繁体   English

Paramterized类,如何引用作为paramterized类型传递的paramterized类型的东西

[英]Paramterized class, how to reference the paramterized type of something passsed as a paramterized type

Sorry if the title sucks, not sure how to ask this question... 对不起,如果标题很糟糕,不知道怎么问这个问题......

Lets say I have some interface Foo that takes a parameter 假设我有一些接口Foo,它接受一个参数

  public interface IFoo<Bar extends IBar>{

      public Bar generateBar();
  }

and I have another class that takes a foo object and will generate a bar object. 我有另一个类,它接受一个foo对象并生成一个bar对象。 I can define it like this. 我可以像这样定义它。

 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();
      }

This all works fine. 一切正常。 However, it seems silly for me to be defining Bar as a parameter of my FooBar class. 但是,将Bar定义为我的FooBar类的参数似乎很愚蠢。 The IFoo object is going to be parametrized to take the Bar value, so I would assume I could infer the type of Bar from whatever parameter the Foo object has; IFoo对象将被参数化以获取Bar值,因此我假设我可以从Foo对象具有的任何参数推断Bar的类型; thus avoiding someone having to provide two parameters every time they define a FooBar object. 从而避免每次定义FooBar对象时必须提供两个参数。

Is there a way I can do this? 有没有办法可以做到这一点? Instead of making Bar part of the FooBar parametrized type just infer it from Foo's parameter? 而不是使Bar成为FooBar参数化类型的一部分,只是从Foo的参数推断它?

edit: The answer appears to be this can't be done, as already answered. 编辑:答案似乎是无法完成,正如已经回答的那样。 However, I'm going to leave this open for another day because I'm hoping someone may post an answer that not only if it can be done, but why it is not possible. 但是,我打算将这个开放一天,因为我希望有人可以发布一个答案,不仅可以做到,而且为什么不可能。 Specifically, is this simply a use case java developers never chose to support, or is there a reason that it's not possible for the same compile time type checking that supports other parametrization checks to infer Bar type by looking at the specific IFoo type parameter. 具体来说,这只是java开发人员从未选择支持的用例,或者是否有一个原因使得支持其他参数化检查的相同编译时类型检查不可能通过查看特定的IFoo类型参数来推断Bar类型。 isn't IFoo parameter able to be determined as well as any parametrized type by the compiler? 编译器不能确定IFoo参数和任何参数化类型吗?

If you care about the actual type parameter to IFoo , then what you have is correct -- declaring the type parameter Bar so it can be the type argument to IFoo when declaring Foo . 如果你关心IFoo的实际类型参数,那么你所拥有的是正确的 - 声明类型参数Bar因此在声明Foo时它可以是IFoo的类型参数。

However, if you don't care in the code what the type parameter to IFoo is, then you can eliminate the Bar type argument and replace the type argument to IFoo with a wildcard bound. 但是,如果您不关心代码中IFoo的类型参数是什么,那么您可以消除Bar类型参数并使用通配符绑定将类型参数替换为IFoo

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

Your getBar method will need to return an IBar . 你的getBar方法需要返回一个IBar

public IBar getBar(){
    return this.foo.generateBar();
}

In order to have a method that creates a Bar object, you need an object of type Class<Bar> . 为了拥有一个创建Bar对象的方法,您需要一个Class<Bar>类型的对象。 Then you can use: 然后你可以使用:

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

    public Bar getBar(){
         return barClass.newInstance();
    }
}

There a various ways to get barClass. 有各种方法来获得barClass。 I'm not sure what design to recommend since you have given us arbitrary types Foo, Bar, etc. 我不确定要推荐什么设计,因为你给了我们任意类型的Foo,Bar等。

A more general solution would be: 更通用的解决方案是:

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

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

You would need to pass Class<Bar> as a parameter somehow. 您需要以某种方式将Class<Bar>作为参数传递。

Presumably your getBar method will return a Bar. 据推测,你的getBar方法将返回一个Bar。 You can't infer the type due to type erasure. 由于类型擦除,您无法推断类型。 You could return a bare Object for casting, but that rather defeats the purpose of generics. 你可以返回一个裸的对象进行投射,但这相当违背了泛型的目的。

Answering my own question, just to mention the approach I used in my specific situation, a work around since what I want can't be done. 回答我自己的问题,只是提到我在特定情况下使用的方法,因为我想做的事情无法完成。 Honestly, it's pretty simple so I should have tried it first, but I got caught up in wondering what can be done with parametrization. 老实说,这很简单,所以我应该先尝试一下,但是我想知道参数化可以做些什么。

My FooBar equivalent now looks like this: 我的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();
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM