Valid Java code that is NOT valid Groovy code?

后端 未结 8 1987
忘了有多久
忘了有多久 2020-12-05 04:50

Most Java code is also syntactically valid Groovy code. However, there are a few exceptions which leads me to my question:

Which constructs/features in Java are syn

相关标签:
8条回答
  • 2020-12-05 05:19

    Complementing the answer by Peter Dolberg:

    Besides valid Java code that is not valid in Groovy, you also need to be wary of code that is valid in both Java and Groovy, but has different results in Groovy. Obvious examples are char literals and 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}");
    

    Implicit accessors:

    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() has been overwritten by GroovyDefaultMethods, which can bite you when you parse the result.

    Map someMap = new HashMap();
    someMap.put("a", "b")
    someMap.toString();
    

    The equals operation

    "foo" == "foo"
    class Foo {public boolean equals() {return true;}}
    new Foo() == new Foo()
    

    Some operator precedence:

    a *= b/100; // Groovy: (a *= b)/100; Java: a *= (b/100);
    

    This is not a correct answer to the original question, since the groovy code is still syntactically valid in itself, but since it has a different result, I think it is worthwhile mentioning it here. The result is that algorithmically, a method may return the wrong(invalid) result when copied from Java to Groovy.

    0 讨论(0)
  • 2020-12-05 05:27

    Here is a list of items that are valid Java 6, but not valid Groovy 1.6. This isn't a complete list, but I think it covers most of the cases. Some of these are permitted by later Groovy versions as noted below.

    (By the way, I think you should note that non-static initialization blocks DO work in Groovy.)

    Any inner class declaration in Groovy 1.6 (1.7 added inner classes):

    including static,

    public class Outer{
      static class Inner{}
    }
    

    non-static,

    public class Outer{
      class Inner{}
    }
    

    local classes,

    public class Outer{
      public static void main(String[] args) {
        class Local{}  
      }
    }
    

    and anonymous classes

    java.util.EventListener listener=new java.util.EventListener(){};
    

    Using Groovy keywords as variables won't work in any Groovy version:

    int def;
    int in;
    int threadsafe;
    int as;
    

    Java array initialization

    String[] stuff=new String[]{"string"};
    int[] array={1,2,3};
    

    Use the Groovy array-literal format by changing {...} to [...].

    Using dollar signs in strings where what follows isn't a valid expression

    String s="$$";
    String s="$def";
    String s="$enum";
    String s="$;";
    String s="$\\";
    //etc.
    

    More than one initializer in a for loop

    for (int i=0, j=0; i < 5; i++) {}
    

    More than one increment in a for loop

    int j=0;
    for (int i=0; i < 5; i++,j++) {}
    

    Breaking up some expressions using newlines

    int a= 2 
    / 2 
    ;
    

    Hint: use a backslash line-continuation in Groovy

    int a= 2 \
    / 2 \
    ;
    

    Ending switch with a case that has no body

    switch(a){
      case 1:
    }
    

    Having a default in a switch with no body

    Applies in both cases where default is at the end

    int a=0;
    switch(a){
        default:
    }
    

    or somewhere in the middle

    switch(a){
        default:
        case 1:
            break;
    }
    

    Annotations with lists

    @SuppressWarnings({"boxing","cast"})
    

    Hint: use Groovy list-literal syntax instead:

    @SuppressWarnings(["boxing","cast"])
    

    Native method declaration

    public native int nativeMethod();
    

    **Class per enum in 1.6 (valid in later Groovy versions) **

    public enum JavaEnum{
      ADD{
        public String getSymbol(){ return "+"; }
      };
      abstract String getSymbol();
    }
    

    Do loop

    do{
      System.out.println("stuff");
    }while(true);
    

    Equality

    While technically == is valid Groovy and Java, it's semantically different. It's one of the reasons you can't rely on just compiling Java as Groovy without changes. Worse, it might seem to work sometimes due to Java string interning.

    The example was too long to add to an existing answer, but the point is that Java code that's syntatically valid as Groovy might behave differently at runtime.

    To get the same result as Java's x == y for two not-null objects you need x.is(y) in Groovy. x == y is valid Groovy, it just does something different.

    The Groovy documentation has a more detailed and broader list of differences.

    0 讨论(0)
  • 2020-12-05 05:28

    Multidimensional arrays, where size is not specified.

    def x=new Object[5][];  // ERROR: expression expected 
    
    def x=new Object[5][2]; // this works
    
    0 讨论(0)
  • 2020-12-05 05:30

    Ok, heres one point:

    int[] i = { 0, 1, 2 };
    

    That is good syntax in java, bad in groovy.

    I don't think you want to assume any given java code will be equivalent in groovy. This site describes some of the differences, which includes things as basic as == not meaning the same thing in both languages. Also, static array initialization is different, and there are no anonymous inner classes.

    This compiles fine in 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();
        }
    }
    

    But is so wrong in Groovy. It gives the following errors in 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.
    

    If you fix those things, it does print what you expect, though.

    If you're looking for newer language syntax issues, like generics or annotations, Groovy supports both of those, though not fully.

    0 讨论(0)
  • 2020-12-05 05:40

    All I can think of for now:

    • int def;
    • String s = "$$";
    0 讨论(0)
  • 2020-12-05 05:41

    Has anyone mention the difference in ==? I took this is from Grails documentation.

    == means equals on all types. In Java there's a wierd part of the syntax where == means equality for primitive types and == means identity for objects.

    0 讨论(0)
提交回复
热议问题