为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用没有原始类型的泛型类型参数编写 Lambda

如何使用没有原始类型的泛型类型参数编写 Lambda

GCT1015 2021-10-20 16:32:15
我有一个带有泛型类型参数的类 Foostatic class Foo<T> {    T get() {return null;}    void set(T t) {}}我想定义一个 java.util.function.Consumer 的实例,不管它的泛型类型参数如何,它都适用于任何 Foo。消费者将简单地调用 Foo 实例上的 set 方法并传入 get 方法返回的值。我决定使用 Lambda 来实现消费者:Consumer<Foo> compilesButWithWarnings = foo -> foo.set(foo.get());不幸的是,我收到此实现的警告。警告是:The method set(Object) belongs to the raw type Foo. References to generic type Foo<T> should be parameterized.如果我尝试将我的 lambda 写为:Consumer<Foo<?>> compileError = foo -> foo.set(foo.get());代码将不再编译给我错误:The method set(capture#1-of ?) in the type Foo<capture#1-of ?> is not applicable for the arguments (capture#2-of ?)我可以想出的一个没有警告编译的解决方案是:Consumer<Foo<?>> worksButRequiresStaticMethod = Test::setFoo;static <ANY> void setFoo(Foo<ANY> foo) {    foo.set(foo.get());}现在还可以,但有点冗长。如果可能的话,我想知道是否有更好的方法来编写此代码而不发出警告且不更改 Foo。
查看完整描述

3 回答

?
沧海一幻觉

TA贡献1824条经验 获得超5个赞

另一种解决方法是使用为您提供使用者实例的通用方法。


例如:


static class Foo<T> {

    T get() {return null;}

    void set(T t) {}

}

public static <T>Consumer<Foo<T>> getFooConsumer() {

    return foo -> foo.set(foo.get());

}

public static void main(String[] args) {

    Consumer<Foo<String>> cons = getFooConsumer();

    Foo<String> foo = new Foo<>();

    foo.set("foo!");

    cons.accept(foo);

}

请注意,由于您的使用者代码实现目前并没有多大用处,因此根据您的实际需求,很难判断此解决方法是否有任何帮助。


您总是可以进一步推动它,并将您选择的值注入到您的已消费中Foo,例如:


public static <T>Consumer<Foo<T>> getFooConsumer(T t) {

    return foo -> foo.set(t);

}


查看完整回答
反对 回复 2021-10-20
?
函数式编程

TA贡献1807条经验 获得超9个赞

无法定义适用于任何泛型类型的实例。泛型类型对于该特定实例必须是已知的,并且是编译器静态类型签名的一部分。

这将起作用:

Consumer<Foo<Object>> c = (Foo<Object> o) -> o.set(o.get());

那是该特定通用参数值 (Object) 的一个实例。

对于每个单独的类型,您都需要另一个“实例”。

说得通?

这就像要求一个任何类型的变量。

一个变量只有一种类型。在编译时已知。


查看完整回答
反对 回复 2021-10-20
?
jeck猫

TA贡献1909条经验 获得超7个赞

如果可以编辑Foo,则可以添加一个方法来在内部处理此问题:


void update() {

    set(get());

}

然后只需使用该方法作为消费者:


Consumer<Foo<?>> consumer = Foo::update;

否则,我认为静态方法是唯一的方法。您需要避免<?>在set调用点使用 通配符类型,因为您可以传递给无界通配符方法参数的唯一内容是null.


查看完整回答
反对 回复 2021-10-20
  • 3 回答
  • 0 关注
  • 159 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信