Painless 如何分派函数

编辑

Painless 使用接收器(receiver)、名称和元数(arity)进行方法分派。例如,s.foo(a, b) 的解析方式是:首先获取 s 的类,然后查找具有两个参数的方法 foo。这与 Groovy 不同,Groovy 使用参数的运行时类型,也与 Java 不同,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 的方法分派感觉会增加大量的复杂性,这将使维护和其他改进更加困难。