表达式语言lambda类型推断

时间:2018-02-23 13:47:24

标签: java-ee lambda el

通常我会这样做:

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)}

2 个答案:

答案 0 :(得分:3)

EL评估者/执行者不知道EL表达式中a的确切类型。由于* operation

,它只知道它应该是Number
${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")失败。

查看ELArithmetic.java#211

的源代码

答案 1 :(得分:-1)

从根本上说,编译器能够推断出类型。如果你稍微改写一下片段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表达式的参数类型时遇到了特殊的困难。