Java编译器接受泛型方法引用,但在作为变量传递时不接受
我有一组带有泛型的复杂类。我不能更改Java编译器接受泛型方法引用,但在作为变量传递时不接受,java,generics,Java,Generics,我有一组带有泛型的复杂类。我不能更改容器和通用容器,但我可以更改其余的 带有.with(Configuration::initialise)的静态版本可以工作 带有(f)的 问题是GenericContainer类上的genericSELF参数,但我无法找出确切原因 示例代码已准备好进行复制/粘贴 初始值设定项: import java.util.function.BiConsumer; public interface Initializer { <C extends Cont
容器
和通用容器
,但我可以更改其余的
- 带有
的静态版本可以工作.with(Configuration::initialise)
- 带有(f)的
SELF
参数,但我无法找出确切原因
示例代码已准备好进行复制/粘贴
初始值设定项:
import java.util.function.BiConsumer;
public interface Initializer {
<C extends Container<?>, S> C initialize(
C container,
BiConsumer<C, S> initializer
);
static <C extends Configuration.Container<?>> Initializer.Builder<C> init(
C container
) {
return new Initializer.Builder<>(container);
}
class Builder<C extends Configuration.Container<?>> {
private final C container;
public Builder(C container) {
this.container = container;
}
public <S> C with(BiConsumer<C, S> initializer) {
Initializer initService = null;
return container;
}
}
}
import java.util.function.BiConsumer;
公共接口初始值设定项{
>初始化器.Builder初始化(
集装箱
) {
返回新的初始值设定项.Builder(容器);
}
类生成器容器_1=初始值设定项
.init(新的GenericContainer())
.带有(配置::初始化);
//不起作用
静态双消费者容器_2=新的初始值设定项.Builder(
新的GenericContainer()
)
.与(f)一起;
}
您不能这样做,因为您需要定义GenericContainer的类型参数,但是java标准中没有定义语法来向lambda提供泛型类型参数。
至于为什么它在方法引用中起作用,我不确定,但可能是类型推断。我可以理解为什么它在第25行(使用函数变量)上不起作用,但不清楚为什么它在第18行(方法引用)上起作用。也许方法引用有一些适用于它们的特殊情况。是的,它很神秘。除此之外,您是否知道如何使函数变量case工作?似乎您可以同时使用lambdas和类型参数。看,我花了一段时间才明白过来。我想我需要这样做,这是不可能的:
staticbiconsumerf=(con,ds)->{}代码>是。方法引用与lambda之间的互换性不如您想象的那么好,这让人有点恼火。如果您不能执行lambda,那么捕获封闭范围的变量就不那么容易了
import java.util.function.BiConsumer;
import javax.sql.DataSource;
public class Configuration {
interface Container<SELF extends Container<SELF>> {}
static class GenericContainer<SELF extends GenericContainer<SELF>>
implements Container<SELF> {}
// works
public static void initialise(GenericContainer<?> container, DataSource ds) {}
public static final GenericContainer<?> CONTAINER_1 = Initializer
.init(new GenericContainer<>())
.with(Configuration::initialise);
// doesn't work
static BiConsumer<GenericContainer<?>, DataSource> f = (con, ds) -> {};
public static final GenericContainer<?> CONTAINER_2 = new Initializer.Builder<>(
new GenericContainer<>()
)
.with(f);
}