大多数Java代码也是语法上有效的Groovy代码。但是,有一些例外情况引起了我的疑问:
Java中的哪些构造/特性在Groovy中在语法上是无效的? 请提供非有效Groovy代码(Groovy 1.6)的Java代码(Java 1.6)的具体示例。
更新
到目前为止,我们已经有五个语法有效的Java代码示例,它们不是有效的Groovy代码:
def
是Groovy中的关键字,但不是Java "$$"
- 字符串 - 在Groovy中解析为无效的GString
-- class Foo { Integer x; { x = 1; } }
这是完整的清单吗?还有其他例子吗?
更新#1:我已经开始提出这个问题了。奖金将授予提供最全面的示例列表的人。到目前为止,我们已经发现了五个例子,但我确信还有更多的例子。所以让他们来吧!
答案 0 :(得分:33)
以下是有效Java 6但无效的Groovy 1.6的项目列表。这不是一个完整的清单,但我认为它涵盖了大多数情况。其中一些是后来Groovy版本允许的,如下所示。
(顺便说一句,我认为你应该注意到非静态初始化块在Groovy中可以工作。)
Groovy 1.6中的任何内部类声明(1.7 added inner classes):
包括静态,
public class Outer{
static class Inner{}
}
非静态,
public class Outer{
class Inner{}
}
本地课程,
public class Outer{
public static void main(String[] args) {
class Local{}
}
}
和匿名类
java.util.EventListener listener=new java.util.EventListener(){};
使用Groovy关键字作为变量在任何Groovy版本中都不起作用:
int def;
int in;
int threadsafe;
int as;
Java数组初始化
String[] stuff=new String[]{"string"};
int[] array={1,2,3};
通过将{...}
更改为[...]
来使用Groovy数组文字格式。
在字符串中使用美元符号,其中后面的内容不是有效表达式
String s="$$";
String s="$def";
String s="$enum";
String s="$;";
String s="$\\";
//etc.
for循环中有多个初始化程序
for (int i=0, j=0; i < 5; i++) {}
for循环中的多个增量
int j=0;
for (int i=0; i < 5; i++,j++) {}
使用换行符分解一些表达
int a= 2
/ 2
;
提示:在Groovy中使用反斜杠行继续
int a= 2 \
/ 2 \
;
使用没有正文的案例的结尾开关
switch(a){
case 1:
}
在没有正文的开关中设置默认值
适用于默认位于最后的两种情况
int a=0;
switch(a){
default:
}
或中间的某个地方
switch(a){
default:
case 1:
break;
}
带有列表的注释
@SuppressWarnings({"boxing","cast"})
提示:改为使用Groovy list-literal语法:
@SuppressWarnings(["boxing","cast"])
原生方法声明
public native int nativeMethod();
** 1.6中的每个枚举类(在以后的Groovy版本中有效)**
public enum JavaEnum{
ADD{
public String getSymbol(){ return "+"; }
};
abstract String getSymbol();
}
执行循环
do{
System.out.println("stuff");
}while(true);
<强>平等强>
虽然技术上==
是有效的Groovy和Java,但它在语义上是不同的。这是你不能仅仅依赖于将Java编译为Groovy而不进行更改的原因之一。更糟糕的是,由于Java字符串实习,它似乎有时会起作用。
这个例子太长了,无法添加到现有答案中,但重点是 语法有效的Java代码,因为Groovy在运行时可能会有不同的行为。
要获得与两个非空对象的Java x == y
相同的结果,您需要在Groovy中使用x.is(y)
。 x == y
是有效的Groovy,只是执行不同的操作。
The Groovy documentation has a more detailed and broader list of differences
答案 1 :(得分:12)
好的,还有一点:
int[] i = { 0, 1, 2 };
这在java中是很好的语法,在groovy中很糟糕。
我认为你不想假设任何给定的java代码在groovy中都是等价的。 This site描述了一些差异,其中包括基本的东西==并不意味着两种语言都是一样的。此外,静态数组初始化是不同的,并且没有匿名内部类。
这在Java 1.6中编译得很好
public class Test2 {
int[] i = { 0, 1, 2 };
private class Class1 {
public void method1() {
if (i[2] == 2) {
System.out.println("this works");
}
}
}
public void method1() {
Class1 class1 = new Class1();
class1.method1();
}
}
但是在Groovy中是如此错误。它在Groovy 1.6中出现以下错误:
unexpected token: 1 @ line 2, column 14.
Class definition not expected here. Possible attempt to use inner class. Inner classes not supported, perhaps try using a closure instead. at line: 4 column: 2.
如果你修复了这些东西,它确实打印了你所期望的东西。
如果您正在寻找更新的语言语法问题,例如泛型或注释,Groovy支持这两者,但并不完全。
答案 2 :(得分:3)
多维数组,其中未指定大小。
def x=new Object[5][]; // ERROR: expression expected
def x=new Object[5][2]; // this works
答案 3 :(得分:2)
Peter Dolberg对答案的补充:
除了在Groovy中无效的有效Java代码之外,您还需要警惕在Java和Groovy中都有效但在Groovy中具有不同结果的代码。明显的例子是char文字和GStrings:
System.out.println(String.valueOf('3' + 3)); // 54 in Java, 33 in Groovy (arithmetic ascii value vs. String concat)
System.out.println("${3+4}");
隐式访问者:
class Foo {public static int counter; public static int bar; public static void getBar() {counter++; return bar;}}
System.out.println(Foo.bar);
System.out.println(Foo.counter); // 0 in Java, 1 in Groovy
toString()已被GroovyDefaultMethods覆盖,在解析结果时可能会咬你。
Map someMap = new HashMap();
someMap.put("a", "b")
someMap.toString();
等于操作
"foo" == "foo"
class Foo {public boolean equals() {return true;}}
new Foo() == new Foo()
一些运算符优先级:
a *= b/100; // Groovy: (a *= b)/100; Java: a *= (b/100);
这不是原始问题的正确答案,因为groovy代码本身在语法上仍然有效,但由于它有不同的结果,我认为值得在此提及。结果是在算法上,当从Java复制到Groovy时,方法可能返回错误的(无效)结果。
答案 4 :(得分:1)
我现在能想到的只有:
int def;
String s = "$$";
答案 5 :(得分:1)
有没有人提到==的区别?我拿这个来自Grails文档。
==表示所有类型的等号。在Java中,语法中有一个奇怪的部分,其中==表示基本类型的相等性,==表示对象的标识。
答案 6 :(得分:1)
在变量名而不是类型之后使用[]声明给定类型的数组在Java中工作但不在Groovy中工作。
byte[] buff = new byte[1024]; // Works
byte buff[] = new byte[1024]; // Not Groovy
Primitive类型文字的结果:byte不能用作方法名称
答案 7 :(得分:0)
非静态初始化块:
class Foo {
Integer x;
{ x = 1; }
}
更新:这实际上是有效的Groovy代码。