Groovy makes heavy use of Java's numeric capabilities. This means that Groovy supports both the primitive and object number types available in Java but with a few enhancements thrown in.
The main highlights are that Groovy provides a more consistent view of numeric types to the developer. This is achieved through two main mechanisms:
These features align with some of the Groovy language's guiding philosophies, namely "everything is an object" and "improved consistency where possible".
The following primitive types are supported:
| Name | Description | Allowed values | Example |
|---|---|---|---|
| byte | 8-bit signed two's complement | -128 to 127 | 42 |
| short | 16-bit signed two's complement | -32,768 to 32,767 | 20000 |
| int | 32-bit signed two's complement | -2,147,483,648 to 2,147,483,647 | 1000000000 |
| long | 64-bit signed two's complement | -9,223,372,036,854,775,808 to +9,223,372,036,854,775,807 | 1000000000000000000 |
| float | 32-bit IEEE 754 floating-point value | 1.40129846432481707e-45 to 3.40282346638528860e+38 | 3.5f |
| double | 64-bit IEEE 754 floating-point value | 4.94065645841246544e-324d to 1.79769313486231570e+308d | 3.5d |
Primitives are nearly always converted ("boxed") to their wrapper types. Autoboxing and unboxing happens automatically behind the scenes if integrating with Java APIs.
In addition to the primitive types, the following object types (sometimes referred to as wrapper types) are allowed:
| Name |
|---|
| java.lang.Byte |
| java.lang.Short |
| java.lang.Integer |
| java.lang.Long |
| java.lang.Float |
| java.lang.Double |
As well as the following classes for supporting arbitrary precision arithmetic:
| Name | Description | Example |
|---|---|---|
| java.math.BigInteger | Immutable arbitrary-precision signed integral numbers | 30g |
| java.math.BigDecimal | Immutable arbitrary-precision signed decimal numbers | 3.5g |
Java automatically imports all classes from the java.lang package. Groovy also does this for the BigInteger and BigDecimal classes, so you don't need to import any of these classes.
You can declare variables using either the primitive or wrapper variants (and optionally provide an initializing literal):
byte b1 = 42 Byte b2 = 42 short s1 = 20000 Short s2 = 20000 int i1 = 1000000000 Integer i2 = 1000000000 long l1 = 1000000000000000000 Long l2 = 1000000000000000000 Long l3 = 42L float f1 = 3.5f Float f2 = 3.5f double d1 = 3.5e40 Double d2 = 3.5e40 Double d3 = 3.5d BigInteger bi = 30g BigDecimal bd = 3.5g [b1, b2, s1, s2, i1, i2, l1, l2, l3, f1, f2, d1, d2, d3, bi, bd].each{ println it.dump() }
which produces this output:
<java.lang.Byte@2a value=42> <java.lang.Byte@2a value=42> <java.lang.Short@4e20 value=20000> <java.lang.Short@4e20 value=20000> <java.lang.Integer@3b9aca00 value=1000000000> <java.lang.Integer@3b9aca00 value=1000000000> <java.lang.Long@aa84b6b3 value=1000000000000000000> <java.lang.Long@aa84b6b3 value=1000000000000000000> <java.lang.Long@2a value=42> <java.lang.Float@40600000 value=3.5> <java.lang.Float@40600000 value=3.5> <java.lang.Double@fbd347d4 value=3.5E40> <java.lang.Double@fbd347d4 value=3.5E40> <java.lang.Double@400c0000 value=3.5> <java.math.BigInteger@1e signum=1 mag=[30] bitCount=-1 bitLength=-1 lowestSetBit=-2 firstNonzeroByteNum=-2 firstNonzeroIntNum=-2> <java.math.BigDecimal@43e intVal=null scale=1 precision=2 stringCache=null intCompact=35>
For simple cases, converting from a string to a number is relatively straight forward. This code illustrates some options for integers (the same variants apply for other numeric types):
def string = "300" // check if it appears to be a number println string.isNumber() // ok, now convert to number in different ways def i3 = string.toInteger() def i4 = string as int def i5 = string as Integer def i6 = new Integer(string) def i7 = Integer.parseInt(string) [i3, i4, i5, i6, i7].each{ println it.dump() }
which produces this output:
true <java.lang.Integer@12c value=300> <java.lang.Integer@12c value=300> <java.lang.Integer@12c value=300> <java.lang.Integer@12c value=300> <java.lang.Integer@12c value=300>
You can also check the validity of strings as a number using regular expressions, e.g.:
integerPattern = /^[+-]?\d+$/ assert '-36' =~ integerPattern assert !('abc' =~ integerPattern) decimalPattern = /^-?(?:\d+(?:\.\d*)?|\.\d+)$/ assert '37.5' =~ decimalPattern
Converting from numbers to strings
In most scenarios using toString() is the appropriate way to convert a number to a string. This only works with object types not primitives but in most cases, this is what Groovy converts your numbers to automatically for you.
println 2.dump() def two = 2.toString() println two println two.dump()
which produces this output:
<java.lang.Integer@2 value=2> 2 <java.lang.String@32 value=[2] offset=0 count=1 hash=50>
Copyright (c) 2008 Paul King. All rights reserved.