gpt4 book ai didi

Java 无法使用双冒号运算符找到正确的重载方法

转载 作者:搜寻专家 更新时间:2023-10-30 21:12:16 24 4
gpt4 key购买 nike

当使用双冒号运算符引用重载方法时,Java 似乎无法确定要使用的正确方法。考虑这个例子:

public class A {
private void setter(final Number value) { }
private void setter(final Optional<Number> value) { }
private void setter2(final Optional<Number> value) { }

private <T> void useSetter(final Consumer<Optional<T>> a) { }

private void callMethod() {
useSetter(this::setter); // Error here
useSetter(this::setter2);
}
}

第一次调用 useSetter 没有编译并给出了以下错误:

Cannot infer type argument(s) for <T> useSetter(Consumer<Optional<T>>)
The type A does not define setter(Optional<Object>) that is applicable here

然而,第二次调用编译正常,这意味着问题出在 setter 的重载上。只有一个 setter 重载适用,所以我不明白为什么这不起作用。

可以通过使用指定参数类型的 lambda 来解决这个问题,但这要冗长得多。

useSetter((final Optional<Number> v) -> setter(v));

有没有更好的方法来处理这种情况,还是我一直在解决这个奇怪的问题?

最佳答案

编译您的 private <T> void useSetter(final Consumer<Optional<T>> a) { } 的捕获方法是 Optional<Object> .编译器试图告诉您它无法强制类型匹配任何已知的捕获。

Main.java:12: error: incompatible types: cannot infer type-variable(s) T
useSetter(this::setter); // Error here
^
(argument mismatch; invalid method reference
no suitable method found for setter(Optional<Object>)
method A.setter(Number) is not applicable
(argument mismatch; Optional<Object> cannot be converted to Number)
method A.setter(Optional<Number>) is not applicable
(argument mismatch; Optional<Object> cannot be converted to Optional<Number>))
where T is a type-variable:
T extends Object declared in method <T>useSetter(Consumer<Optional<T>>)

一个解决方案是使用 private <T> void setter(final Optional<? super T> value) { } 创建一个边界对于泛型参数化可选类型。另一种选择是向编译器暗示一些强制能力 private void setter(final Optional<? super Number> value) { } .

class A<T> {
private void setter(final Number value) { }
private <T> void setter(final Optional<? super T> value) { }
private void setter2(final Optional<Number> value) { }

private <T> void useSetter(final Consumer<Optional<T>> a) { }

private void callMethod() {
useSetter(this::setter); // no more error
useSetter(this::setter2);
}

public static void main(String [] args){

}
}

class B {
private void setter(final Number value) { }
private void setter(final Optional<? super Number> value) { }
private void setter2(final Optional<Number> value) { }

private <T> void useSetter(final Consumer<Optional<T>> a) { }

private void callMethod() {
useSetter(this::setter); // no more error
useSetter(this::setter2);
}

public static void main(String [] args){

}
}

您可以查看 ideone here .

这两个选项都不是完美的,因为它会通过允许 Optional<Object> 为您的代码引入一些可替代性。将被传递,但是如果您避免直接使用原始类型,您应该没问题。

关于Java 无法使用双冒号运算符找到正确的重载方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45329062/

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