Ste*_*ler 7 java generics lambda type-inference
我正在使用lambda在下面的Java程序中实现一个功能接口.当lambda作为参数传递给泛型方法时,编译器会标记"不兼容类型"错误,因为它推断lambda实现了Func <Shape>接口,该接口让编译器将lambda参数("thing")解释为当lambda尝试将其传递给需要Round类型参数的方法(testRound)时,为Shape类型.这个错误对我有意义.
但是等效方法引用不会引发错误消息.我一直误以为lambda和可以替换lambda的方法引用是可以互换的.在这里,事实并非如此.
public class Main
{
public static void main(String... args)
{
methodB(thing -> Main.testRound(thing)); // incompatible types
methodB(Main::testRound); // no problem here
}
static <T extends Shape> void methodB(Func<T> function)
{
}
static boolean testRound(Round thing)
{
return true;
}
}
interface Func<T>
{
boolean test(T ob);
}
class Shape
{
}
class Round extends Shape
{
}
Run Code Online (Sandbox Code Playgroud)
当lambda失败时,为什么方法引用成功?
UPDATE
Vince Emigh在下面找到了我已经标记为接受的答案.虽然这不是我的问题的一部分,但是有四种方法可以解决这样一个事实:Func<Shape>如果一个人真的被使用lambdas ,那么lambda只被推断为类型:
// Use a type witness.
Main.<Round>methodB(thing -> testRound(thing));
// Make the lambda's argument type explicit.
methodB((Round thing) -> testRound(thing));
// Cast the argument.
methodB(thing -> testRound((Round)thing));
// Store the lambda reference in a Func<Round> variable.
Func<Round> lambda = thing -> testRound(thing);
methodB(lambda);
Run Code Online (Sandbox Code Playgroud)
我没有看到任何理由更喜欢其中一个而不是方法参考,除非有人认为lambdas的密度稍低(并且可能更具可读性).但是,如果你想要它们,它们就在那里.
\n\n\n与 lambda 表达式不同,方法引用可以与泛型函数类型(即具有类型参数的函数类型)一致。这是因为 lambda 表达式需要能够声明类型参数,但没有语法支持这一点;而对于方法引用,不需要这样的声明。
\n
由于未指定类型参数,因此 lambda 表达式会引发错误。这会导致T编译为Shape(如您的帖子中提到的),因为没有任何东西可以帮助推断参数的类型。
至于方法引用,由于可以从方法的参数推断类型,因此不需要显式类型参数,如上面的 JLS 语句中所述。
\n| 归档时间: |
|
| 查看次数: |
272 次 |
| 最近记录: |