gpt4 book ai didi

java - 对一元静态方法的方法引用在 Function 和 BiFunction 参数类型之间不明确

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:27:12 25 4
gpt4 key购买 nike

考虑以下简化的测试用例:

import java.util.AbstractList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;
public final class Example {
static class PairList<A, B> {
public void replaceAllSecond(Function<? super B, ? extends B> secondFunction) {}
public void replaceAllSecond(BiFunction<? super A, ? super B, ? extends B> secondFunction) {}
}

static class ImmutableList<E> extends AbstractList<E> {
public static <E> ImmutableList<E> copyOf(Iterable<? extends E> elements) {return null;}
public static <E> ImmutableList<E> copyOf(Collection<? extends E> elements) {return null;}
public static <E> ImmutableList<E> copyOf(Iterator<? extends E> elements) {return null;}
public static <E> ImmutableList<E> copyOf(E[] elements) {return null;}

@Override public E get(int index) {return null;}
@Override public int size() {return 0;}
}

public static void foo() {
PairList<Integer, List<Integer>> list = new PairList<>();
list.replaceAllSecond(x -> ImmutableList.copyOf(x)); //accepted
list.replaceAllSecond(ImmutableList::copyOf); //error
}
}

使用 Oracle JDK 8u40 中的 javac 进行编译,接受使用 lambda 调用 replaceAllSecond,但传递方法引用的调用被拒绝,并出现以下错误:

Example.java:26: error: reference to replaceAllSecond is ambiguous
list.replaceAllSecond(ImmutableList::copyOf); //error
^
both method replaceAllSecond(Function<? super B,? extends B>) in PairList and method replaceAllSecond(BiFunction<? super A,? super B,? extends B>) in PairList match
where B,A are type-variables:
B extends Object declared in class PairList
A extends Object declared in class PairList
1 error

我不明白为什么采用 BiFunction 的重载可能适用于此。来自 JLS 15.12.2.1 (省略了一些项目符号):

A member method is potentially applicable to a method invocation if and only if all of the following are true:

  • If the member is a fixed arity method with arity n, the arity of the method invocation is equal to n, and for all i (1 ≤ i ≤ n), the i'th argument of the method invocation is potentially compatible, as defined below, with the type of the i'th parameter of the method.

An expression is potentially compatible with a target type according to the following rules:

  • A method reference expression (§15.13) is potentially compatible with a functional interface type if, where the type's function type arity is n, there exists at least one potentially applicable method for the method reference expression with arity n (§15.13.1), and one of the following is true:

    • The method reference expression has the form ReferenceType :: [TypeArguments] Identifier and at least one potentially applicable method is i) static and supports arity n, or ii) not static and supports arity n-1.

按照我的解释,BiFunction 的函数类型元数是 2,但是 copyOf 的所有重载都是静态的并且具有元数 1,因此方法引用可能不是与 BiFunction 参数兼容,因此 replaceAllSecond(BiFunction) 可能不适用。

我是不是误解了 JLS,或者这是一个 javac 错误? JDK-8026231描述了更新 javac 以实现规范,但该错误已在 2013 年解决,在 Java 8 首次发布之前(2014 年 3 月)。

最佳答案

您的示例可以进一步简化为以下内容:

import java.util.Collection;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;

public final class Example {
static class PairList<A, B> {
public void replaceAllSecond(Function<? super B, ? extends B> secondFunction) {}
public void replaceAllSecond(BiFunction<? super A, ? super B, ? extends B> secondFunction) {}
}

public static <E> List<E> copyOf(Iterable<? extends E> elements) {return null;}
public static <E> List<E> copyOf(Collection<? extends E> elements) {return null;}

public static void foo() {
PairList<Integer, List<Integer>> list = new PairList<>();
list.replaceAllSecond(x -> Example.copyOf(x)); //accepted
list.replaceAllSecond(Example::copyOf); //error
}
}

我想这是一个 javac 问题,因为这段代码在 Java-9 抢先体验版本(甚至像 9ea57 这样很老的版本)中编译得很好,而在 Java-8(即使是最新的更新)中编译失败。

关于java - 对一元静态方法的方法引用在 Function 和 BiFunction 参数类型之间不明确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36257374/

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