有效的 Java 代码不是有效的 Groovy 代码?
Posted
技术标签:
【中文标题】有效的 Java 代码不是有效的 Groovy 代码?【英文标题】:Valid Java code that is NOT valid Groovy code? 【发布时间】:2010-10-15 19:32:53 【问题描述】:大多数 Java 代码也是语法上有效的 Groovy 代码。但是,有一些例外情况导致我提出我的问题:
Java 中的哪些构造/特性在 Groovy 中在语法上是无效的? 请提供不是有效 Groovy 代码 (Groovy 1.6) 的 Java 代码 (Java 1.6) 的具体示例。
更新:
到目前为止,我们已经得到了五个语法上有效的 Java 代码示例,这些示例不是有效的 Groovy 代码:
-
数组初始化
内部类
def
在 Groovy 中是关键字,但在 Java 中不是
"$$"
-strings - 在 Groovy 中被解析为无效的 GString
s
非静态初始化块-- class Foo Integer x; x = 1;
这是完整的列表吗?还有其他例子吗?
更新 #1: 我已经开始悬赏来解决这个问题。赏金将授予提供最全面示例列表的人。到目前为止,我们已经发现了五个例子,但我敢肯定还有更多的例子。所以让他们来吧!
【问题讨论】:
【参考方案1】:这里列出了有效的 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 列表文字语法:
@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 字符串实习,它有时似乎可以工作。
该示例太长,无法添加到现有答案中,但重点是 语法上作为 Groovy 有效的 Java 代码在运行时可能会表现不同。
要获得与 Java 的 x == y
相同的结果,对于两个非空对象,您需要在 Groovy 中使用 x.is(y)
。 x == y
是有效的 Groovy,它只是做了一些不同的事情。
The Groovy documentation has a more detailed and broader list of differences.
【讨论】:
看起来内部类示例不再有效; Groovy 现在支持内部类。见groovy-lang.org/…。其他一些需要对 Groovy 列表语法进行简单的更改,但用 Java 形式编写的绝对无效。【参考方案2】:好的,这里有一点:
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 支持这两者,但不完全支持。
【讨论】:
投反对票的不是我,但是:这不是被问到的。没有人说 Java 代码在 groovy 中是等价的。问题是在 Groovy 中哪些语法上有效的 Java 代码在语法上无效。 我不会这样解释这个问题:“Groovy 不支持 Java 中的哪些构造/功能?”我读到的行为不同。也许这个问题需要更清楚。【参考方案3】:多维数组,未指定大小。
def x=new Object[5][]; // ERROR: expression expected
def x=new Object[5][2]; // this works
【讨论】:
从外观上看,这在以后的 Groovy 版本中得到了支持。【参考方案4】:补充 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 时可能会返回错误(无效)的结果。
【讨论】:
平等绝对是个大陷阱【参考方案5】:暂时能想到的:
int def;
String s = "$$";
【讨论】:
【参考方案6】:有没有人提到 == 的区别?这是我从 Grails 文档中获取的。
== 表示所有类型都相等。在 Java 中,有一个奇怪的语法部分,其中 == 表示原始类型的相等,而 == 表示对象的标识。
【讨论】:
【参考方案7】:在变量名后使用 [] 代替类型声明给定类型的数组在 Java 中有效,但在 Groovy 中无效。
byte[] buff = new byte[1024]; // Works
byte buff[] = new byte[1024]; // Not Groovy
原始类型文字的结果:字节不能用作方法名称
【讨论】:
【参考方案8】:非静态初始化块:
class Foo
Integer x;
x = 1;
更新:这实际上是有效的 Groovy 代码。
【讨论】:
见鬼?我也不知道那是有效的 Java。 测试确认它确实在创建类的实例时运行。怪异的。你知道的越多。 这在 Groovy 中有效。至少它适用于 Groovy 1.5.7 和 1.6。 嗯,它也对我有用。我可以发誓这过去是行不通的。哦,好吧,否决答案。 值得一票;有些人不知道这适用于 Java,您纠正说这实际上也适用于 Groovy。 :3以上是关于有效的 Java 代码不是有效的 Groovy 代码?的主要内容,如果未能解决你的问题,请参考以下文章
获得使用 Java 或 Groovy 填充的有效 oauth_signature 的绝对最少代码?
如何自动将 Java 代码转换为 Groovy 代码 [关闭]
Groovy循环控制 ( Java 语法循环 | 默认的 IntRange 构造函数 | 可设置翻转属性的 IntRange 构造函数 | 可设置是否包含 to 的构造函数 | 0..9 简写 )(代