【Groovy文档翻译】有些事情你可以做,但最好不要做 博客分类: Java-Groovy/Grails GroovyJava
Groovy是一个强大的工具。像其他强大的工具一样(想象一个链锯),它需要用户具备某些专业知识和注意,否则,后果可能很严重。
下面的代码片段在Groovy中是允许的,但是常常会导致无意的行为或者无法理解的问题。只要不这样做就可使你自己免遭一些新的和不熟练的Groovy程序员时常会经历的沮丧。
1. 像访问属性一样访问对象的类型
使用.class
而不是.getClass()
是可以的-只要你确切的知道你有什么样的对象。可是那样你根本就不需要它了。否则,你就有得到null
或者其他值的风险,而不是对象的类型。
a = [:] println a.class.simpleName // NullPointerException, because a.class is null. |
2. 不恰当的省略方法参数前后的圆括号
除非你确定,否则最好为参数使用圆括号。
例如,一个方法名后的左括号必须永远把参数列表围起来。
println a*(b+c) // is OK println (a+b)*c // NullPointer exception, because println (a+b) results in null. |
3. 把一个新行放到代码中的错误位置
尽管它的原意是表示在下一行继续,但这会使得编译器假定这是一个完整的语句。而且它不会总是像下面的例子那样显而易见。
myVariable = "This is a very long statement continuing in the next line. Result is=" + 42 // this line has no effect |
4. 忘记写比较操作符的第二个等于符号
结果,一个比较表达式变成了一个赋值表达式。
while (a=b) { ... } // will be executed as long as b is true (Groovy-truth) String s = "A"; boolean b = s = "B" // b becomes true |
(有一种措施是永远将常量表达式放到比较操作符的前面。)
5. 当覆写一个方法时指定错误的返回类型(只针对Groovy版本<1.5.1)
这样的方法可能会被认为是重载的(一个具有相同名字的方法)而不能按照预期被调用。
def toString() { ... } // does not override toString() inherited from Object |
6. 无视其他对象的隐私
每当访问类的方法,值域或者属性的时候,确保你没有牵涉到private或者protected的成员。目前Groovy完全不区分public,private和protected的成员,所以你自己当心了。
z = [1,2,3] z.size = 10 // size is private; errors when trying to access z[3] to z[9], although z.size()==10 'more'.value = 'less' // results in "more"=="less" |
7. 轻率的动态编程
在用Groovy的动态能力添加或者改变类的方法或属性前,检查是否与预期的功能有冲突。
String.metaClass.class = Integer // results in 'abc'.getClass()==java.lang.Integer |
8. 字符串连接
尽管在Java中,你可以用”+“符号连接字符串。但是Java只需要”+“表达式的两项中有一个是字符串类型即可,无论是前面的还是后面的。Java会为你写的”+“表达式调用非字符串类型对象的toString()
方法。但是在Groovy中,只有在你的“+”表达式中的第一项正确实现了plus()
方法的情况下才可能是安全的,因为Groovy会搜索并使用它。在Groovy GDK中,只有Number和String/StringBuffer/Character类实现了plus()
方法来连接字符串。为避免意想不到的情况,永远使用GString。
// Java code, it works boolean v = true; System.out.println(" foo "+v); System.out.println(v+" foo "); |
// Groovy code boolean v = true println " foo "+v // It works println v+" foo " // It fails with MissingMethodException: No signature of method: java.lang.Boolean.plus() |