Groovy
2
DZone, Inc.
|
www.dzone.com
tech facts at your fingertips
Hot
Tip
Actively look for opportunities to implement
operator methods in your own Groovy class.
This often leads to more expressive code.
Typical candidates are ==, <=>, +, -, <<,
and isCase(). See also Ranges.
Language Elements (Classes and Scripts), continued
When a .groovy file or any other source of Groovy code
contains code that is not enclosed in a class declaration,
then this code is considered a Script, e.g.
println "Hello World"
Scripts differ from classes in that they have a Binding that
serves as a container for undeclared references (that are not
allowed in classes).
println text // expected in Binding
result = 1 // is put into Binding
Optional Typing
Static types can be used like in Java and will be obeyed
at runtime. Dynamic typing is used by replacing the type
declaration with the def keyword. Formal parameters to
method and closure declarations can even omit the def.
Properties
Properties are declared as fields with the default visibility
modifier, no matter what type is used.
class MyClass {
String stringProp
def dynamicProp
}
Java-style getters and setters are compiled into the bytecode
automatically.
Properties are referred to like
println obj.stringProp // getter
obj.dynamicProp = 1 // setter
regardless of whether obj was written in Java or Groovy, the
respective getters/setters will be called.
Multimethods
Methods are dispatched by the runtime type, allowing code like
class Pers {
String name
boolean equals(Pers other) {
name == other.name
}
}
assert new Pers(name:'x') == new Pers(name:'x')
assert new Pers(name:'x') != 1
Customizable Operators
Operators can be customized by implementing/ overriding
the respective method.
Numbers
All Groovy numbers are objects, not primitive types. Literal
declarations are:
Customizable Operators, continued
Special Operators
OPERATORS
SIMPLE DATATYPES
Operator Method
a + b a.plus(b)
a – b a.minus(b)
a * b a.multiply(b)
a / b a.div(b)
a % b a.mod(b)
a++
++a
a.next()
Type Example literals
java.lang.Integer 15, 0x1234ffff
java.lang.Long 100L, 100l
java.lang.Float 1.23f, 4.56F
java.lang.Double 1.23d, 4.56D
java.math.BigInteger 123g, 456G
java.math.BigDecimal 1.23, 4.56, 1.4E4, 2.8e4, 1.23g, 1.23G
Operator Method
a--
--a
a.previous()
a**b a.power(b)
a|b a.or(b)
a&b a.and(b)
a^b a.xor(b)
~a ~a a.bitwiseNegate() // sometimes referred to as negate
| +a a.positive() // sometimes referred to as unaryMinus
| -a a.negative() // sometimes referred to as unaryPlus
a[b] a.getAt(b)
a[b] = c a.putAt(b, c)
a << b a.leftShift(b)
a >> b a.rightShift(b)
a >>> b a.rightShiftUnsigned(b)
switch(a){
case b:
}
[a].grep(b)
if(a in b)
b.isCase(a)
// b is a classier
a == b a.equals(b)
a != b ! a.equals(b)
a <=> b a.compareTo(b)
a > b a.compareTo(b) > 0
a >= b a.compareTo(b) >= 0
a < b a.compareTo(b) < 0
a <= b a.compareTo(b) <= 0
a as B a.asType(B)
Operator Meaning Name
a ? b : c if (a) b else c ternary if
a ?: b a ? a : b Elvis
a?.b a==null ? a : a.b null safe
a(*list) a(list[0], list[1], ...) spread
list*.a() [list[0].a(), list[1].a() ...] spread-dot
a.&b reference to method b in
object a as closure
method closure
a.@eld direct eld access dot-at