Java泛型:在方法调用中使用参数化接口

Java Generics: using parameterized interface in method calls

我想存储一个函数以应用于 class 的任何实例。因为我想为不同的 classes 执行此操作,所以我在存储和应用代码中使用了一个接口。但是我的类型变量有一些问题:

我有一个界面

public interface SomeInterface<P>

还有一个实现class

public class SomeClass implements SomeInterface<Object>

以及处理程序

public class SomeHandler {
   public <R> void someMethod(Function<SomeInterface<R>,R> someFunction) {}
}

和代码

public void someTest() {
    Function<SomeClass,Object> someFunction = a -> new Object();
    SomeHandler handler = new SomeHandler();
    handler.someMethod(someFunction); //error here
}

不会工作。

标记位置的错误是"No Instance(s) of type variable(s) R exist so that SomeClass conforms to SomeInterface"

我已经尝试使用抽象 class 而不是接口。这也没有用。

我做了一些研究,发现了一个包含 lambda 表达式的错误。删除 lambda 表达式并没有解决问题。 另一页提示 OpenJdk 中的错误,建议更改类型变量的顺序。因为我正在使用 java 函数 class,所以我无法执行此操作。

我也试过获取 Oracle Jdk,但是我不能在这台机器上做任何事情。

欢迎任何想法!

someTest() 中的函数更改为:

Function<SomeInterface<Object>, Object> someFunction = a -> new Object();

更新 取决于您的评论:

您可以将您的处理程序方法推广到更多类似的东西:

public <R> void someMethod(Function<? extends SomeInterface<R>, R> someFunction) {}

这允许您使用类似以下的功能:

Function<SomeOtherClass, MyObject> someFunction = a -> new MyObject();
Function<SomeClass,Object> someFunction = a -> new Object();

不是 Function<SomeInterface<R>,R>.

的实例

您可以执行 : 更改 someFunction 变量的类型;或者您可以在方法调用中内联 lambda,并隐藏类型声明:

handler.someMethod(a -> new Object());

或者,要在调用站点保留现有类型,请将方法签名更改为:

public <R, S extends SomeInterface<R>>
    void someMethod(Function<S, R> someFunction)

但请注意,为了能够使用文字 null 以外的任何内容调用 someFunction.apply,您必须传入 S(或包含 S,如 CollectionOptional) 作为附加方法参数。

如果你不需要调用 someFunction.apply(问题是你为什么需要它......),你可以删除 S 类型变量,然后使用:

public <R> void someMethod(Function<? extends SomeInterface<R>, R> someFunction)