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 的方法调度感觉会增加大量复杂性,这将使维护和其他改进变得更加困难。