Painless 如何调度函数编辑

Painless 使用接收者、名称和 元数 来进行方法调度。例如,s.foo(a, b) 通过首先获取 s 的类,然后查找具有两个参数的方法 foo 来解析。这与 Groovy 不同,Groovy 使用参数的 运行时类型,而 Java 使用参数的编译时类型。

这种方式的结果是 Painless 不支持像 Java 那样重载方法,这在允许来自 Java 标准库的类时会导致一些问题。例如,在 Java 和 Groovy 中,Matcher 有两种方法:group(int)group(String)。Painless 无法同时允许这两种方法,因为它们具有相同的名称和相同数量的参数。因此,它只有 group(int)namedGroup(String)

我们对这种不同的方法调度方式有几个理由

  1. 它使对 def 类型进行操作变得更简单,并且可能更快。使用接收者、名称和元数意味着当 Painless 看到对 def 对象的调用时,它可以调度适当的方法,而无需对参数类型进行昂贵的比较。对于使用 def 类型参数的调用也是如此。
  2. 它保持一致性。如果涉及任何 def 类型参数,Painless 像 Groovy 一样行为,而其他情况下像 Java 一样行为,这将非常奇怪。如果它始终像 Groovy 一样行为,速度会很慢。
  3. 它保持 Painless 的可维护性。添加类似 Java 或 Groovy 的方法调度 感觉 会增加大量的复杂性,这将使维护和其他改进变得更加困难。