Differences with Java
Groovy tries to be as natural as possible for Java developers. We’ve tried to follow the principle of least surprise when designing Groovy, particularly for developers learning Groovy who’ve come from a Java background.
Here we list all the major differences between Java and Groovy.
1. Default imports
All these packages and classes are imported by default, i.e. you do not have to use an explicit import
statement to use them:
-
java.io.*
-
java.lang.*
-
java.math.BigDecimal
-
java.math.BigInteger
-
java.net.*
-
java.util.*
-
groovy.lang.*
-
groovy.util.*
2. Multi-methods
In Groovy, the methods which will be invoked are chosen at runtime. This is called runtime dispatch or multi-methods. It means that the method will be chosen based on the types of the arguments at runtime. In Java, this is the opposite: methods are chosen at compile time, based on the declared types.
The following code, written as Java code, can be compiled in both Java and Groovy, but it will behave differently:
int method(String arg){return1;}
int method(Object arg){return2;}
Object o ="Object";
int result = method(o);
In Java, you would have:
assertEquals(2, result);
Whereas in Groovy:
assertEquals(1, result);
That is because Java will use the static information type, which is that o
is declared as an Object
, whereas Groovy will choose at runtime, when the method is actually called. Since it is called with a String
, then the String
version is called.
3. Array initializers
In Groovy, the { … }
block is reserved for closures. That means that you cannot create array literals with this syntax:
int[] array = {1,2,3}
You actually have to use:
int[] array = [1,2,3]
4. Package scope visibility
In Groovy, omitting a modifier on a field doesn’t result in a package-private field like in Java:
class Person {
String name
}
Instead, it is used to create a property, that is to say a private field, an associated getter and an associated setter.
It is possible to create a package-private field by annotating it with @PackageScope
:
class Person {
@PackageScope String name
}
5. ARM blocks
ARM (Automatic Resource Management) block from Java 7 are not supported in Groovy. Instead, Groovy provides various methods relying on closures, which have the same effect while being more idiomatic. For example:
Path file = Paths.get("/path/to/file");
Charset charset = Charset.forName("UTF-8");
try(BufferedReader reader = Files.new BufferedReader(file, charset)) {
String line;
while((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
can be written like this:
new File('/path/to/file').eachLine('UTF-8') {
println it
}
or, if you want a version closer to Java:
new File('/path/to/file').withReader('UTF-8') { reader ->
reader.eachLine {
println it
}
}
6. Inner classes
The implementation of anonymous inner classes and nested classes follows the Java lead, but you should not take out the Java Language Spec and keep shaking the head about things that are different. The implementation done looks much like what we do for groovy.lang.Closure , with some benefits and some differences. Accessing private fields and methods for example can become a problem, but on the other hand local variables don’t have to be final. |
6.1. Static inner classes
Here’s an example of static inner class:
class A {
static class B {}
}
new A.B()
The usage of static inner classes is the best supported one. If you absolutely need an inner class, you should make it a static one.
6.2. Anonymous Inner Classes
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
CountDownLatch called = new CountDownLatch(1)
Timer timer = new Timer()
timer.schedule(newTimerTask() {
void run() {
called.countDown()
}
},0)
assert called.await(10,TimeUnit.SECONDS)
6.3. Creating Instances of Non-Static Inner Classes
In Java you can do this:
public class Y {
public class X {}
public X foo() {
return new X();
}
public static X createX(Y y) {
return y.new X();
}
}
Groovy doesn’t support the y.new X()
syntax. Instead, you have to write new X(y)
, like in the code below:
public class Y {
public class X {}
public X foo() {
return new X()
}
public static X createX(Y y) {
return new X(y)
}
}
Caution though, Groovy supports calling methods with one parameter without giving an argument. The parameter will then have the value null. Basically the same rules apply to calling a constructor. There is a danger that you will write new X() instead of new X(this) for example. Since this might also be the regular way we have not yet found a good way to prevent this problem. |
7. Lambdas
Java 8 supports lambdas and method references:
Runnable run =()->System.out.println("Run");
list.forEach(System.out::println);
Java 8 lambdas can be more or less considered as anonymous inner classes. Groovy doesn’t support that syntax, but has closures instead:
Runnable run = { println 'run'}
list.each { println it } // or list.each(this.&println)
8. GStrings
As double-quoted string literals are interpreted as GString
values, Groovy may fail with compile error or produce subtly different code if a class with String
literal containing a dollar character is compiled with Groovy and Java compiler.
While typically, Groovy will auto-cast between GString
and String
if an API declares the type of a parameter, beware of Java APIs that accept an Object
parameter and then check the actual type.
9. String and Character literals
Singly-quoted literals in Groovy are used for String
, and double-quoted result in String
or GString
, depending whether there is interpolation in the literal.
assert'c'.getClass() == String
assert"c".getClass() == String
assert"c${1}".getClass() in GString
Groovy will automatically cast a single-character String
to char
only when assigning to a variable of type char
. When calling methods with arguments of type char
we need to either cast explicitly or make sure the value has been cast in advance.
char a='a'
assertCharacter.digit(a,16)==10:'But Groovy does boxing'
assertCharacter.digit((char)'a',16)==10
try{
assert Character.digit('a',16)==10
assert false:'Need explicit cast'
} catch(MissingMethodException e) {
}
Groovy supports two styles of casting and in the case of casting to char
there are subtle differences when casting a multi-char strings. The Groovy style cast is more lenient and will take the first character, while the C-style cast will fail with exception.
// for single char strings, both are the same
assert((char)"c").class==Character
assert("c"aschar).class==Character
// for multi char strings they are not
try {
((char)'cx')=='c'
assertfalse:'will fail - not castable'
}
catch(GroovyCastException e) {
}
assert('cx'aschar)=='c'
assert'cx'.asType(char)=='c'
10. Primitives and wrappers
Because Groovy uses Objects for everything, it autowraps references to primitives. Because of this, it does not follow Java’s behavior of widening taking priority over boxing. Here’s an example using int
int i
m(i)
void m(long l) {
println "in m(long)"
}
void m(Integer i) {
println "in m(Integer)"
}
This is the method that Java would call, since widening has precedence over unboxing. | |
This is the method Groovy actually calls, since all primitive references use their wrapper class. |
11. Behaviour of ==
In Java ==
means equality of primitive types or identity for objects. In Groovy ==
translates to a.compareTo(b)==0
, if they are Comparable
, and a.equals(b)
otherwise. To check for identity, there is is
. E.g. a.is(b)
.
12. Conversions
Java does automatic widening and narrowing conversions.
Converts to |
||||||||
Converts from |
boolean |
byte |
short |
char |
int |
long |
float |
double |
boolean |
- |
N |
N |
N |
N |
N |
N |
N |
byte |
N |
- |
Y |
C |
Y |
Y |
Y |
Y |
short |
N |
C |
- |
C |
Y |
Y |
Y |
Y |
char |
N |
C |
C |
- |
Y |
Y |
Y |
Y |
int |
N |
C |
C |
C |
- |
Y |
T |
Y |
long |
N |
C |
C |
C |
C |
- |
T |
T |
float |
N |
C |
C |
C |
C |
C |
- |
Y |
double |
N |
C |
C |
C |
C |
C |
C |
- |
* 'Y' indicates a conversion Java can make, 'C' indicates a conversion Java can make when there is an explicit cast, 'T` indicates a conversion Java can make but data is truncated, 'N' indicates a conversion Java can’t make.
Groovy expands greatly on this.
Converts to |
||||||||||||||||||
Converts from |
boolean |
Boolean |
byte |
Byte |
short |
Short |
char |
Character |
int |
Integer |
long |
Long |
BigInteger |
float |
Float |
double |
Double |
BigDecimal |
boolean |
- |
B |
N |
N |
N |
N |
N |
N |
N |
N |
N |
N |
N |
N |
N |
N |
N |
N |
Boolean |
B |
- |
N |
N |
N |
N |
N |
N |
N |
N |
N |
N |
N |
N |
N |
N |
N |
N |
byte |
T |
T |
- |
B |
Y |
Y |
Y |
D |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Byte |
T |
T |
B |
- |
Y |
Y |
Y |
D |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
short |
T |
T |
D |
D |
- |
B |
Y |
D |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Short |
T |
T |
D |
T |
B |
- |
Y |
D |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
char |
T |
T |
Y |
D |
Y |
D |
- |
D |
Y |
D |
Y |
D |
D |
Y |
D |
Y |
D |
D |
Character |
T |
T |
D |
D |
D |
D |
D |
- |
D |
D |
D |
D |
D |
D |
D |
D |
D |
D |
int |
T |
T |
D |
D |
D |
D |
Y |
D |
- |
B |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Integer |
T |
T |
D |
D |
D |
D |
Y |
D |
B |
- |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
long |
T |
T |
D |
D |
D |
D |
Y |
D |
D |
D |
- |
B |
Y |
T |
T |
T |
T |
Y |
Long |
T |
T |
D |
D |
D |
T |
Y |
D |
D |
T |
B |
- |
Y |
T |
T |
T |
T |
Y |
BigInteger |
T |
T |
D |
D |
D |
D |
D |
D |
D |
D |
D |
D |
- |
D |
D |
D |
D |
T |
float |
T |
T |
D |
D |
D |
D |
T |
D |
D |
D |
D |
D |
D |
- |
B |
Y |
Y |
Y |
Float |
T |
T |
D |
T |
D |
T |
T |
D |
D |
T |
D |
T |
D |
B |
- |
Y |
Y |
Y |
double |
T |
T |
D |
D |
D |
D |
T |
D |
D |
D |
D |
D |
D |
D |
D |
- |
B |
Y |
Double |
T |
T |
D |
T |
D |
T |
T |
D |
D |
T |
D |
T |
D |
D |
T |
B |
- |
Y |
BigDecimal |
T |
T |
D |
D |
D |
D |
D |
D |
D |
D |
D |
D |
D |
T |
D |
T |
D |
- |
* 'Y' indicates a conversion Groovy can make, 'D' indicates a conversion Groovy can make when compiled dynamically or explicitly cast, 'T` indicates a conversion Groovy can make but data is truncated, 'B' indicates a boxing/unboxing operation, 'N' indicates a conversion Groovy can’t make.
The truncation uses Groovy Truth when converting to boolean
/Boolean
. Converting from a number to a character casts the Number.intvalue()
to char
. Groovy constructs BigInteger
and BigDecimal
usingNumber.doubleValue()
when converting from a Float
or Double
, otherwise it constructs using toString()
. Other conversions have their behavior defined by java.lang.Number
.
13. Extra keywords
There are a few more keywords in Groovy than in Java. Don’t use them for variable names etc.
-
as
-
def
-
in
-
trait
相关推荐
Making Java Groovy is a practical handbook for developers who want to blend Groovy into their day to day work with Java It starts by introducing the key differences between Java and Groovy and how you...
C++与C#是两种广泛应用的编程语言,它们在很多方面都有显著的区别。本文将详细探讨这两种语言之间的主要差异,帮助开发者理解它们各自的特点。 1. 命名空间和成员访问: - C# 使用点号(.)来分隔命名空间、类以及...
Talk Show Differences Between China and America from the Perspective of the Form and Express.zip
The Differences Between Chinese and American Cultures from the Perspective of Politeness Utterances.zip
在IT领域,尤其是在企业软件开发中,理解不同的增强技术至关重要。本文将深入探讨EEWB(Enhancement Element Workbench)和BDT(Business Data Type)之间的差异,这两种工具都是用于SAP CRM系统中的对象扩展和定制...
英语与汉语的语言结构差异是一个复杂且广泛的话题,涉及语言学的多个层面。首先需要明确的是,任何两种语言之间的结构差异都是各自文化和思维模式差异的反映。这一点在英汉语言对比中尤为明显。...
Designed for Java engineers who want to learn Python, this book walks you through the differences between Java 8 and Python 2.7 syntax using examples from both languages. Specifically, the book will ...
java java_leetcode题解之Numbers With Same Consecutive Differences.java
Employment-related differences between male and female school psychologists Psychulony in Ihe Schools Yollrme 31. July /994 EMPLOYMENT-RELATED DIFFERENCES BETWEEN MALE AND FEMALE SCHOOL ...
Differences between urban and rural school psychology: Training implications P \ i i h o l o ~ i in rhr Srhvolr I Y X I . l R . 191-196 DIFFERENCES BETWEEN URBAN AND RURAL SCHOOL PSYCHOLOGY: ...
### 最小二乘法与卡尔曼滤波的区别 在GPS导航系统和其他位置定位技术中,两种最常用的估计方法是最小二乘法(Least Squares, LS)和卡尔曼滤波(Kalman Filtering, KF)。这两种方法虽然表面上看起来有很大区别,但...
【标题】:初识SQL:SQL Server与Oracle之间的差异 【描述】:这份资料主要针对SQL初学者,尤其是从SQL Server环境转向Oracle的用户,详细介绍了两者在语法、功能和概念上的不同之处。 【标签】:SQL ...
S32K11x和S32K142微控制器(MCUs)是NXP半导体公司生产的两个系列的产品。虽然两者具有许多共通模块,但也存在一些显著差异,尤其是在核心架构、内存选项、外设配置、中断映射和软件迁移的兼容性等方面。...
Diagnostic differences between educationally handicapped and learning disabled students Pr~.rhulugv in the Schuul.r PPVT and MSCA with Autistic Children 469 1980. 17. 469-473 SCHOPLER, E. ...
Differences-between-LIN20-and-LIN21 (1)
Identification of statistically significant differences between scaled scores and psycholinguistic ages on the ITPA IDENTIFICATION OF STATISTICALIiY SIGNIFICANT DIFFERENCES BETWEEN SCALED SCORES ...
数据库系统概念课后习题答案
Philosophical differences between early childhood education and special education: Issues for school psychologists Psychology in Ihe Schools Volume 23, April 1986 PHILOSOPHICAL DIFFERENCES ...