有效的Java代码是无效的Groovy代码?
大多数Java代码也是语法上有效的Groovy代码。 但是,有一些例外情况引起了我的疑问:
Java中哪些构造/特性在语法上在Groovy中无效? 请提供非有效Groovy代码(Groovy 1.6)的Java代码(Java 1.6)的具体示例。
更新:
到目前为止,我们已经有五个语法有效的Java代码示例,它们不是有效的Groovy代码:
- 数组初始化
- 内课
-
def
是Groovy中的关键字,但不是Java中的关键字 -
"$$"
-strings – 在Groovy中解析为无效的GString
- 非静态初始化块
-- class Foo { Integer x; { x = 1; } }
-- class Foo { Integer x; { x = 1; } }
这是完整的清单吗? 还有其他例子吗?
更新#1:我已经开始提出这个问题了。 赏金将授予提供最全面的示例列表的人。 到目前为止,我们已经发现了五个例子,但我确信还有更多的例子。 所以让他们来吧!
以下是有效Java 6的项目列表,但不是有效的Groovy 1.6。 这不是一个完整的清单,但我认为它涵盖了大多数情况。
(顺便说一句,我认为你应该注意到非静态初始化块在Groovy中可以工作。)
任何内部类声明
包括静态,
public class Outer{ static class Inner{} }
非静态,
public class Outer{ class Inner{} }
当地class级,
public class Outer{ public static void main(String[] args) { class Local{} } }
和匿名课程
java.util.EventListener listener=new java.util.EventListener(){};
使用Groovy关键字作为变量
int def; int in; int threadsafe; int as;
数组初始化
String[] stuff=new String[]{"string"}; int[] array={1,2,3};
在字符串中使用美元符号,其中后面的内容不是有效的表达式
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 ;
结束开关,没有机身的箱子
switch(a){ case 1: }
在没有正文的开关中有默认值
适用于默认情况结束时的两种情况
int a=0; switch(a){ default: }
或者在中间的某个地方
switch(a){ default: case 1: break; }
带有列表的注释
@SuppressWarnings({"boxing","cast"})
本机方法声明
public native int nativeMethod();
每个枚举的类
public enum JavaEnum{ ADD{ public String getSymbol(){ return "+"; } }; abstract String getSymbol(); }
做循环
do{ System.out.println("stuff"); }while(true);
好吧,还有一点:
int[] i = { 0, 1, 2 };
这在java中是很好的语法,在groovy中很糟糕。
我不认为你想假设任何给定的java代码在groovy中是等价的。 这个网站描述了一些差异,其中包括基本的东西==并不意味着两种语言都是一样的东西。 此外,静态数组初始化是不同的,并且没有匿名内部类。
这在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.
如果你修复了这些东西,它确实会打印你所期望的东西。
如果您正在寻找更新的语言语法问题,例如generics或注释,Groovy支持这两者,尽管不完全。
多维数组,其中未指定大小。
def x=new Object[5][]; // ERROR: expression expected def x=new Object[5][2]; // this works
我现在所能想到的只有:
-
int def;
-
String s = "$$";
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时,方法可能返回错误(无效)的结果。
非静态初始化块:
class Foo { Integer x; { x = 1; } }
更新:这实际上是有效的Groovy代码。
有没有人提到==的区别? 我拿这个来自Grails文档。
==表示所有类型的等于。 在Java中,语法中有一个奇怪的部分,其中==表示基本类型的相等性,==表示对象的标识。
在变量名称而不是类型之后使用[]声明给定类型的数组在Java中工作但不在Groovy中工作。
byte[] buff = new byte[1024]; // Works
byte buff[] = new byte[1024]; // Not Groovy
Primitive类型文字中的结果:byte不能用作方法名称