Действительный код Java, который НЕ является допустимым Groovy кодом?

Большинство Java-кода также синтаксически корректны Groovy code. Однако есть несколько исключений, которые приводят меня к моему вопросу:

Какие конструкторы/функции в Java синтаксически недействительны в Groovy? Просьба представить конкретные примеры кода Java (Java 1.6), который НЕ является допустимым Groovy code (Groovy 1.6).

Update:

До сих пор у нас есть пять примеров синтаксически допустимого кода Java, который недействителен Groovy code:

  • Инициализация массива
  • Внутренние классы
  • def - это ключевое слово в Groovy, но не в Java
  • "$$" -strings - анализируется как недопустимый GString в Groovy
  • Нестатические блоки инициализации -- class Foo { Integer x; { x = 1; } }

Это полный список? Другие примеры?

Обновление # 1: Я начал щедрость, чтобы ответить на этот вопрос. Награда будет предоставлена ​​лицу, предоставляющему наиболее полный список примеров. Пока мы раскрыли пять примеров, но я уверен, что там есть еще кое-что. Поэтому держите их при себе!

Ответ 1

Ниже приведен список элементов, действительный Java 6, но недействительный Groovy 1.6. Это не полный список, но я думаю, что он охватывает большинство случаев.

(Кстати, я думаю, вы должны отметить, что блоки нестатического инициализации DO работают в Groovy.)

Любое объявление внутреннего класса

включая статические,

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 ключевых слов в качестве переменных

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);

Ответ 2

Хорошо, одна точка:

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 поддерживает оба из них, хотя и не полностью.

Ответ 3

Многомерные массивы, размер которых не указан.

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

def x=new Object[5][2]; // this works

Ответ 4

Все, о чем я могу думать сейчас:

  • int def;
  • String s = "$$";

Ответ 5

Дополняя ответ Питером Дольбергом:

Помимо действительного кода Java, который недействителен в Groovy, вам также необходимо быть осторожным с кодом, который действителен как на 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.

Ответ 6

Нестатические блоки инициализации:

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

UPDATE: Фактически это действительно код Groovy.

Ответ 7

Кто-нибудь упоминает разницу в ==? Я взял это из документации Grails.

== означает equals для всех типов. В Java есть странная часть синтаксиса, где == означает равенство для примитивных типов, а == означает идентификацию для объектов.

Ответ 8

Объявление массива заданного типа с использованием [] после имени переменной вместо типа работает в Java, но не Groovy.

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

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

Результаты в литерале примитивного типа: байт не может использоваться как имя метода