表达式语言 lambda 类型推断
Expression Language lambda type inference
通常我会这样做:
Function<Integer, Integer> a = b -> b * 2;
System.out.println(a.apply(3)); // prints 6
我惊讶地发现以下 EL 表达式有效:
${a = b -> b * 2; a(3)}
以上EL表达式的结果为6
。在片段 2 中声明 a
但在片段 1 中需要类型信息时,编译器如何确定类型?
即使这样编译和执行也很好:
${(b -> b * 2)(3)}
从根本上说,编译器能够推断类型。如果您稍微改写代码片段 1,您可以获得无需显式声明类型 Integer
:
即可编译的内容
public static <V, R> R apply(Function<V, R> foo, V v) {
return foo.apply(v);
}
System.out.println(apply(b -> b * 2, 3)); // prints 6
这接近语法:${(b -> b * 2)(3)}
编译器在推断 lambda 表达式的参数类型方面存在特定困难。
EL 计算器/执行器不知道 EL 表达式中 a 的确切类型。它只知道它应该是一个 Number
因为 * operation
${a = b -> b * 2; a(3)}
看看这些结果:
${a = b -> b * 2; a(3)}
6
${a = b -> b * 2; a('32')}
64
${a = b -> b * 2; a('32s')}
java.lang.NumberFormatException: For input string: "32s"
所以只有在运行时你才会得到一个异常,因为 Long.parse("32s")
失败了。
的源代码
通常我会这样做:
Function<Integer, Integer> a = b -> b * 2;
System.out.println(a.apply(3)); // prints 6
我惊讶地发现以下 EL 表达式有效:
${a = b -> b * 2; a(3)}
以上EL表达式的结果为6
。在片段 2 中声明 a
但在片段 1 中需要类型信息时,编译器如何确定类型?
即使这样编译和执行也很好:
${(b -> b * 2)(3)}
从根本上说,编译器能够推断类型。如果您稍微改写代码片段 1,您可以获得无需显式声明类型 Integer
:
public static <V, R> R apply(Function<V, R> foo, V v) {
return foo.apply(v);
}
System.out.println(apply(b -> b * 2, 3)); // prints 6
这接近语法:${(b -> b * 2)(3)}
编译器在推断 lambda 表达式的参数类型方面存在特定困难。
EL 计算器/执行器不知道 EL 表达式中 a 的确切类型。它只知道它应该是一个 Number
因为 * operation
${a = b -> b * 2; a(3)}
看看这些结果:
${a = b -> b * 2; a(3)}
6
${a = b -> b * 2; a('32')}
64
${a = b -> b * 2; a('32s')}
java.lang.NumberFormatException: For input string: "32s"
所以只有在运行时你才会得到一个异常,因为 Long.parse("32s")
失败了。