从泛型函数返回泛型类型

发布于 2024-07-22 05:22:24 字数 1410 浏览 9 评论 0原文

我们有一个或多或少类似于以下的方法。 但是我们目前返回列表 在函数 bla() 中,它将在运行时返回 List

我正在寻找一种方法来使这两者成为

List<Interface> =  troubleFuction(foo, bar.getCLass());;

可能

List<Bar> = troubleFuction(foo, bar.getCLass());;

。 基本上我希望它返回与接口兼容的列表 但是这会出现以下错误

*类型不匹配:无法从 List to List*

有什么方法可以使这种返回类型成为可能,或者运行时擦除是否会使这种

public <T1 extends Interface, T2 extends Interface> List<"problem"> troubleFunction( T1 in, Class<T2> clazz) {
  return in.doStuffWhichGeneratesAlistOF(clazz)
}

public void bla() {
  Foo foo = new Foo(); // implements interface
  Bar bar = new Bar(); // implements interface
  List<Interface> ifaces = toubleFuction(foo, bar.getCLass());
  List<Bar> mustAlsoWork = toubleFuction(foo, bar.getCLass());
}

编辑变得不可能: 在许多现有的代码库中,该方法的调用方式如下,

List<Bar> result = troubleFunction(List<Interface> list, Bar.class);

因此该返回类型必须保持兼容(重写/重构不是一个选项),

本质上我希望该方法返回 List 如果调用为

troublefunction(foo, Bar.class);

and 列表 当调用时

troublefunction(foo, Bar.class);

we have a method more or less like the following.
however we currently return List
which in function bla() would return List<Bar> at runtime.

I'm looking for a way to make both

List<Interface> =  troubleFuction(foo, bar.getCLass());;

and

List<Bar> = troubleFuction(foo, bar.getCLass());;

possible.
basicaly i want it to return List which would be compatible with interface
however this gives the following error

*Type mismatch: cannot convert from List<capture#3-of ? extends Bar> to List<Interface>*

is there any way to make this return type possible or does runtime erasure make this impossible

public <T1 extends Interface, T2 extends Interface> List<"problem"> troubleFunction( T1 in, Class<T2> clazz) {
  return in.doStuffWhichGeneratesAlistOF(clazz)
}

public void bla() {
  Foo foo = new Foo(); // implements interface
  Bar bar = new Bar(); // implements interface
  List<Interface> ifaces = toubleFuction(foo, bar.getCLass());
  List<Bar> mustAlsoWork = toubleFuction(foo, bar.getCLass());
}

edit:
in a lot of the existing code base the method is called like

List<Bar> result = troubleFunction(List<Interface> list, Bar.class);

thus this return type must stay compatible (rewrite/re-factor is not an option)

essentially i want the method to return List<? super Bar> if called as

troublefunction(foo, Bar.class);

and
List<? super Foo> when called as

troublefunction(foo, Bar.class);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

清风疏影 2024-07-29 05:22:24

一般来说,在这种情况下,您需要显式传递一个用于返回值的 Class 对象(一般参数化)。

然而,看起来您已经在您的情况下完成了此操作,因此将 troubleFunction 声明为返回 List 是否不起作用? 或者,如果您想保持通用,则让它返回 List

Generally speaking in situations like this, you need to explicitly pass a Class object in (generically parameterised) which is used for the return value.

However it looks like you've done this already in your case, so would it not work for troubleFunction to be declared to return List<T2>? Alternatively, if you want to keep it general then have it return List<? extends Interface>.

快乐很简单 2024-07-29 05:22:24

您没有向我们提供足够的信息来真正告诉我们您需要做什么。 例如,您没有向我们提供 doStuffWhichGeneratesAlistOF() 的类型签名,也没有告诉我们它的作用。 而且您没有告诉我们“in”参数的类型与所有这些有什么关系。

当然,方法的返回类型可以是泛型的。可能。 例如,

public <T extends Interface> List<T> troubleFunction(Interface in, Class<? extends T> clazz) {
  List<T> result = new ArrayList<T>();
  result.add(clazz.newInstance());
  return result;
}

然后您可以像这样直接调用该方法,它会起作用(您不需要显式指定类型参数,因为它是从赋值中推断出来的):

List<Interface> iface = this.troubleFunction(foo, bar.getCLass());

但是看看上面的代码中如何返回结果in.doStuffWhichGeneratesAlistOF(clazz),您可能还必须将该方法的返回类型设为通用。 但我无法真正帮助您,因为我们没有有关该方法的任何信息。

You're not giving us enough information to really tell what you need to do. For example, you didn't give us the type signature of doStuffWhichGeneratesAlistOF() or tell us what it does. And you didn't tell us what the type of the "in" argument has to do with all of this.

Sure, it's possible to have the return type of a method be generic. For example,

public <T extends Interface> List<T> troubleFunction(Interface in, Class<? extends T> clazz) {
  List<T> result = new ArrayList<T>();
  result.add(clazz.newInstance());
  return result;
}

And then you could call the method directly like this and it would work (you don't need to specify the type parameter explicitly because it's inferred from the assignment):

List<Interface> iface = this.troubleFunction(foo, bar.getCLass());

But seeing as how in your code above you return the result of in.doStuffWhichGeneratesAlistOF(clazz), you would probably have to make the return type of that method generic also. But I can't really help you on that because we don't have any information on that method.

无风消散 2024-07-29 05:22:24

据我了解,在目标类型之前先查看参数类型以推断通用参数。 所以,我想你需要明确指定通用参数,我认为它是这样的

List<Interface> iface = this.<Interface>troubleFunction(foo, bar.getCLass());

public <T extends Interface> List<T> troubleFunction(
    T in, Class<? extends T> clazz
) {

As I understand it, the argument types are looked at before the target type to infer the generic arguments. So, I guess you need to explicitly specify the generic arguments, which I think goes something like this:

List<Interface> iface = this.<Interface>troubleFunction(foo, bar.getCLass());

where

public <T extends Interface> List<T> troubleFunction(
    T in, Class<? extends T> clazz
) {
诠释孤独 2024-07-29 05:22:24

我又看了一遍,问题是我想使用“超级”返回类型
我正在寻找的签名或多或少是:

 public <T1 extends interface, T2 super T1> List<T2> getAList(Class<T1> clazz); 

这是不可能的

i've looked at this again and the problem was that i wanted to use a 'super' return type
the signature i was looking for was more or less:

 public <T1 extends interface, T2 super T1> List<T2> getAList(Class<T1> clazz); 

which is not possible

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文