gpt4 book ai didi

java - 通用功能接口(interface)和方法引用被类型删除弄乱了

转载 作者:搜寻专家 更新时间:2023-11-01 02:42:43 25 4
gpt4 key购买 nike

我有以下通用 FunctionalInterface:

@FunctionalInterface
public interface FooInterface<T> {
void bar(T arg);
}

还有这个 ArrayList 后代:

public class FooList<T> extends ArrayList<FooInterface<T>> {
public void doFoo(T arg) {
for(Iterator<FooInterface<T>> i = iterator(); i.hasNext(); ) {
i.next().bar(arg);
}
}
}

现在,我使用方法引用和类型删除编写这段代码:

protected void doFoo(Object arg) { }

private void doStuff() {
FooInterface f = this::doFoo;

List<FooInterface> list = new ArrayList<>();
list.add(f2);
list.add(this::doFoo);

FooList list2 = new FooList();
list2.add(f2);
list2.add(this::doFoo); // <-- Compiler chokes here, complaining that this is not a FunctionalInterface
}

这让我很困惑。为什么编译器会同意我将 this::doFoo 分配给 FooInterface 变量,并在代码的第一部分调用 List.add() ,只是拒绝从 ArrayList 派生的类调用相同的 add() 方法?

在我的后代类中,类型删除似乎发生了一些奇怪的事情,但是什么?这是一个错误吗?我做了不受支持的事情吗?

最佳答案

FooList(没有类型参数)被称为原始类型。 4.8. Raw Types是这样说的:

The superclasses (respectively, superinterfaces) of a raw type are the erasures of the superclasses (superinterfaces) of any of the parameterizations of the generic type.

这意味着原始 FooList 只是原始 ArrayList 并且方法 add 接受 Object

因为 Object 不是函数式接口(interface),所以它不能成为 lambda 的目标。这也行不通:

Object f = this::doFoo;

完整的编译器错误或多或少证实了这一切:

error: no suitable method found for add(this::doFoo)
list2.add(this::doFoo); // <-- Compiler chokes here, complaining that this is not a FunctionalInterface
^
method <strong>Collection.add(Object)</strong> is not applicable
(argument mismatch; <strong>Object is not a functional interface</strong>)

“修复”它的一种方法是做一些像下面这样的棘手的事情:

public class FooList<T> extends ArrayList<FooInterface<T>> {
@Override
public boolean add(FooInterface<T> e) {
return super.add(e);
}
...
}

真正的解决方案是 not use raw types但是既然你提到了“删除”,那么你似乎在某种程度上意识到了这一点。没有理由使用原始类型。

关于java - 通用功能接口(interface)和方法引用被类型删除弄乱了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30063170/

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