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

kno*_*orv 24 java grails groovy

大多数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:我已经开始提出这个问题了.奖金将授予提供最全面的示例列表的人.到目前为止,我们已经发现了五个例子,但我确信还有更多的例子.所以让他们来吧!

Pet*_*erg 33

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

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

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

包括静态,

public class Outer{
  static class Inner{}
}
Run Code Online (Sandbox Code Playgroud)

非静态,

public class Outer{
  class Inner{}
}
Run Code Online (Sandbox Code Playgroud)

当地班级,

public class Outer{
  public static void main(String[] args) {
    class Local{}  
  }
}
Run Code Online (Sandbox Code Playgroud)

和匿名课程

java.util.EventListener listener=new java.util.EventListener(){};
Run Code Online (Sandbox Code Playgroud)

使用Groovy关键字作为变量将无法在任何Groovy版本中使用:

int def;
int in;
int threadsafe;
int as;
Run Code Online (Sandbox Code Playgroud)

Java数组初始化

String[] stuff=new String[]{"string"};
int[] array={1,2,3};
Run Code Online (Sandbox Code Playgroud)

通过更改{...}为使用Groovy数组文字格式[...].

在字符串中使用美元符号,其中后面的内容不是有效表达式

String s="$$";
String s="$def";
String s="$enum";
String s="$;";
String s="$\\";
//etc.
Run Code Online (Sandbox Code Playgroud)

for循环中有多个初始值设定项

for (int i=0, j=0; i < 5; i++) {}
Run Code Online (Sandbox Code Playgroud)

for循环中有多个增量

int j=0;
for (int i=0; i < 5; i++,j++) {}
Run Code Online (Sandbox Code Playgroud)

使用换行符分解一些表达式

int a= 2 
/ 2 
;
Run Code Online (Sandbox Code Playgroud)

提示:在Groovy中使用反斜杠行继续

int a= 2 \
/ 2 \
;
Run Code Online (Sandbox Code Playgroud)

结束开关,没有机身的箱子

switch(a){
  case 1:
}
Run Code Online (Sandbox Code Playgroud)

在没有正文的开关中有默认值

适用于默认情况结束时的两种情况

int a=0;
switch(a){
    default:
}
Run Code Online (Sandbox Code Playgroud)

或者在中间的某个地方

switch(a){
    default:
    case 1:
        break;
}
Run Code Online (Sandbox Code Playgroud)

带有列表的注释

@SuppressWarnings({"boxing","cast"})
Run Code Online (Sandbox Code Playgroud)

提示:使用Groovy list-literal语法代替:

@SuppressWarnings(["boxing","cast"])
Run Code Online (Sandbox Code Playgroud)

本机方法声明

public native int nativeMethod();
Run Code Online (Sandbox Code Playgroud)

**1.6中的每个枚举类(在以后的Groovy版本中有效)**

public enum JavaEnum{
  ADD{
    public String getSymbol(){ return "+"; }
  };
  abstract String getSymbol();
}
Run Code Online (Sandbox Code Playgroud)

做循环

do{
  System.out.println("stuff");
}while(true);
Run Code Online (Sandbox Code Playgroud)

平等

虽然技术上==是有效的Groovy和Java,但它在语义上是不同的.这是你不能仅仅依赖于将Java编译为Groovy而不进行更改的原因之一.更糟糕的是,由于Java字符串实习,它似乎有时会起作用.

这个例子太长了,无法添加到现有答案中,但重点是,作为Groovy在语法上有效的Java代码在运行时可能会有不同的行为.

要获得与Groovy中x == y需要的两个非空对象的Java相同的结果x.is(y).x == y是有效的Groovy,它只是做了不同的事情.

Groovy文档具有更详细和更广泛的差异列表.


Joh*_*ood 12

好吧,还有一点:

int[] i = { 0, 1, 2 };
Run Code Online (Sandbox Code Playgroud)

这在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();
    }
}
Run Code Online (Sandbox Code Playgroud)

但是在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.
Run Code Online (Sandbox Code Playgroud)

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

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