gpt4 book ai didi

java - 推断泛型类中的参数类型,这些参数类型是所提供参数的嵌套泛型类型

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:02:01 25 4
gpt4 key购买 nike

我有一个类:

class MyClass<F extends Field, G extends OtherClass<F>> {
...
}

问题是,给定类的信息 G ,我可以很容易地推断出类型 F .但是,现在实例化需要我这样做:

new MyClass<ConcreteField, ConcreteOtherClass>();

使用<>语法,我使用了一个小 hack 并添加了一个构造函数:

public MyClass(Class<G> gClass) {}

这允许我使用菱形语法,因为编译器现在能够轻松推断类型:

new MyClass<>(ConcreteOtherClass.class);

有没有办法要求我只传入类型 G (如“构造函数 hack”中所述)而不使用上述构造函数?

最佳答案

我想了一会儿,但我没有找到任何允许这种类型推断的简单泛型结构。

关于专门的伪参数构造函数,值得注意的是您不需要传递实际的 Class实例;任何允许推断的类型 G , 包括 G本身会起作用。例如,如果您更改 public MyClass(Class<G> gClass) {} public MyClass(G ignored) {} 的构造函数您可以使用 new MyClass<>((ConcreteOtherClass)null) 实例化该类.

您还可以隐藏 null通过添加提供虚拟值的方法来引用和编写没有任何类型转换的实例化:

class MyClass<F extends Field, G extends OtherClass<F>> {

public MyClass() {}
public MyClass(G dummy) {}

public static <T> T infer() {
return null;
}
}

然后你可以像这样用完整的类型推断来实例化这个类:

new MyClass<>(MyClass.<ConcreteOtherClass>infer())

既然您要求的解决方案没有专门的构造函数,我将添加这样的解决方案。但是您会发现这并没有真正提高代码的可维护性:

interface Instantiator<T extends OtherClass<?>> extends Runnable {
default <M extends MyClass<?,? extends T>> M get(Supplier<? extends M> s) {
return s.get();
}
static <X extends OtherClass<?>> Instantiator<X> i() {
return ()->{};
}
}

使用这个辅助类,您可以实例化 MyClass使用默认构造函数作为类型推断

Instantiator.<ConcreteOtherClass>i().get(MyClass::new)

请注意,这个两步实例化也适用于普通类型,但是使这个 Instantiator一个功能接口(interface)并通过 lambda 表达式实例化它是使其成为类型安全单例的唯一方法,即在当前 Oracle 的实现中,将只有一个 Instantiator 的实例。在运行时内,无论您如何对其进行参数化,因为它是无状态的(并且确实存在只是为了让编译器满意......)。

关于java - 推断泛型类中的参数类型,这些参数类型是所提供参数的嵌套泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27721387/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com