为什么Groovy将java.lang.String.length()替换为size()?

12

维基百科的有关Groovy编程语言的当前文章解释说:“大多数有效的Java文件也是有效的Groovy文件”,并给出以下Java代码示例:

for (String it : new String[] {"Rod", "Carlos", "Chris"})
    if (it.length() <= 4)
        System.out.println(it);

然后在Groovy中同样实现:

["Rod", "Carlos", "Chris"].findAll{it.size() <= 4}.each{println it}

注意,在第一个例子中,我们使用了非常普通的Java方法,java.lang.String.length()。在第二个例子中,这个方法已经神秘地被替换成了一个名为size()的方法调用。我已经验证过第二个例子是有效的Groovy代码,并且具有正确的行为。

java.lang.String没有一个名为size()的方法。Groovy不会为了自己的目的而对String进行子类化:

String s = ""
Class c = s.getClass()
println c.getName() // "java.lang.String"

它也不会向 String 对象中添加额外的方法:

// [...]
for (def method : c.getMethods()) {
    println method.getName()
}
// prints a whole bunch of method names, no "size"

然而,这段代码仍然能够正常工作:

// [...]
println s.size() // "0"

我找不到任何Groovy文档来解释这个问题。

  • size()方法从哪里来?
  • 为什么它不出现在对象上?
  • 为什么要添加它?
  • length()有什么问题,为什么不推荐使用?
  • java.lang.String还有哪些其他附加方法?
  • 其他标准类呢?

只是一个猜测:Groovy可能正在使用自己的元编程来实现这样的魔法。 - JimmyB
1
“length()”有什么问题吗?- 我一直觉得length()不是很一致(更不用说Array.length了!),而集合API使用的是size() - JimmyB
1
它并不会“替换”长度和大小(如问题中所暗示),而是添加了一个新的size方法,而length仍然存在。 - tim_yates
除此之外,您可以编写一个函数,该函数接受一个字符串或集合,并根据其大小执行某些操作,而无需首先检查它是什么类型。 - tim_yates
size()和length()都不是非常一致的,它们应该是getSize()和getLength()...但是String早于Bean规范,而且不应更改旧的Java。 - billjamesdev
显示剩余2条评论
2个回答

16

Groovy为字符串和各种其他类添加了许多方法。所有这些便利方法都是Groovy强大之处的一部分。

java.lang.String实现了java.lang.CharSequence,这就是它从中获取(大部分)魔力的地方。例如,size()。Groovy向大多数可以拥有您认为是大小的内容的对象添加了一个size()方法,以便您可以在整个范围内使用一致的方法。 length()仍然完全有效, Groovy不会删除它。

要查看Groovy添加的部分方法,请查看GDK,特别是CharSequenceCollection


0
我建议您阅读Groovy类StringGroovyMethods的文档,它提供了关于Groovy如何运作的简单解释。

静态方法是使用目标类作为第一个参数的方法,例如public static String reverse(String self)为String提供了一个reverse()方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接