有效的Java代码是无效的Groovy代码?

java grails groovy

6569 观看

8回复

19787 作者的声誉

大多数Java代码也是语法上有效的Groovy代码。但是,有一些例外情况引起了我的疑问:

在Groovy中,Java中的哪些构造/特性在语法上是无效的?请提供Java代码(Java 1.6)的具体示例,该代码不是有效的Groovy代码(Groovy 1.6)。

更新:

到目前为止,我们已经有五个语法有效的Java代码示例,它们不是有效的Groovy代码:

  1. 数组初始化
  2. 内课
  3. def 是Groovy中的关键字,但不是Java中的关键字
  4. "$$"-strings - GString在Groovy中解析为无效的
  5. 非静态初始化块 -- class Foo { Integer x; { x = 1; } }

这是完整的清单吗?还有什么例子吗?

更新#1:我已经开始提出这个问题了。奖金将授予提供最全面的示例列表的人。到目前为止,我们已经发现了五个例子,但我确信还有更多的例子。所以让他们来吧!

作者: knorv 的来源 发布者: 2009 年 3 月 26 日

回应 (8)


12

9401 作者的声誉

好吧,还有一点:

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.

如果你修复了这些东西,它确实会打印你所期望的东西。

如果您正在寻找更新的语言语法问题,例如泛型或注释,Groovy支持这两者,尽管不完全。

作者: John Ellinwood 发布者: 26.03.2009 09:48

1

290600 作者的声誉

我现在能想到的一切:

  • int def;
  • String s = "$$";
作者: Michael Borgwardt 发布者: 26.03.2009 10:15

0

2503 作者的声誉

非静态初始化块:

class Foo {
  Integer x;   
  { x = 1; }
}

更新:这实际上是有效的Groovy代码。

作者: Jen S. 发布者: 31.03.2009 06:04

32

1541 作者的声誉

决定

以下是有效Java 6但不是有效Groovy 1.6的项目列表。这不是一个完整的清单,但我认为它涵盖了大多数情况。其中一些是后来的Groovy版本允许的,如下所述。

(顺便说一下,我认为你应该注意非静态初始化块在Groovy中工作。)

Groovy 1.6中的任何内部类声明(1.7内部类):

包括静态,

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文档具有更详细和更广泛的差异列表

作者: Peter Dolberg 发布者: 11.04.2009 07:12

3

339 作者的声誉

多维数组,其中未指定大小。

def x=new Object[5][];  // ERROR: expression expected 

def x=new Object[5][2]; // this works
作者: user339047 发布者: 27.06.2010 06:09

1

756 作者的声誉

有没有人提到==的区别?我拿这个来自Grails文档。

==表示所有类型的等于。在Java中,语法中有一个奇怪的部分,其中==表示基本类型的相等性,==表示对象的标识。

作者: Joe 发布者: 03.02.2014 11:13

0

484 作者的声誉

在变量名而不是类型之后使用[]声明给定类型的数组在Java中工作但不在Groovy中工作。

byte[] buff = new byte[1024]; // Works

byte buff[] = new byte[1024]; // Not Groovy

Primitive类型文字中的结果:byte不能用作方法名称

作者: DSoa 发布者: 28.04.2014 07:10

1

3995 作者的声誉

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时,方法可能返回错误(无效)的结果。

作者: tkruse 发布者: 22.09.2014 12:45
32x32