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

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

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

Обновление:

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

  1. Инициализации массива
  2. Внутренние классы
  3. def - ключевое слово в Groovy, но не в Java.
  4. "$$"-strings - анализируются как недопустимые GStrings в Groovy
  5. Блоки нестатической инициализации -- class Foo { Integer x; { x = 1; } }

Это полный список? Еще примеры?

Обновление №1: я объявил конкурс, чтобы ответить на этот вопрос. Награда будет предоставлена ​​тому, кто предоставит наиболее полный список примеров. На данный момент мы обнаружили пять примеров, но я уверен, что есть еще несколько. Так что держите их!


person knorv    schedule 26.03.2009    source источник


Ответы (8)


Вот список элементов, которые допустимы для 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:

@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.

Пример был слишком длинным, чтобы добавить его к существующему ответу, но дело в том, что код Java, который синтаксически действителен как Groovy, может вести себя по-другому во время выполнения.

Чтобы получить тот же результат, что и x == y в Java для двух ненулевых объектов, вам понадобится x.is(y) в Groovy. x == y действительно Groovy, он просто делает что-то другое.

В документации Groovy есть более подробный и более широкий список различий.

person Peter Dolberg    schedule 11.04.2009
comment
Похоже, что пример внутреннего класса больше не действителен; Groovy теперь поддерживает внутренние классы. См. groovy-lang.org/. Некоторые из других нуждаются в простом изменении синтаксиса списка Groovy, но они определенно недействительны в том виде, в каком они написаны в форме Java. - person Craig Ringer; 07.11.2018

Хорошо, вот один момент:

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

person John Ellinwood    schedule 26.03.2009
comment
Это не я проголосовал против, но: спросили не об этом. Никто не сказал, что Java-код будет эквивалентен Groovy. Вопрос заключался в том, какой ситактически действительный код Java синтаксически не действителен в Groovy. - person Michael Borgwardt; 27.03.2009
comment
Я не так интерпретирую вопрос: какие конструкции / функции в Java не поддерживаются в Groovy? Я читал, что веду себя иначе. Возможно, вопрос нужно прояснить. - person TofuBeer; 27.03.2009

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

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

def x=new Object[5][2]; // this works
person user339047    schedule 27.06.2010
comment
Это поддерживается внешним видом в более поздних версиях Groovy. - person Craig Ringer; 07.11.2018

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

Помимо допустимого кода 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);

Это неправильный ответ на исходный вопрос, поскольку отличный код все еще синтаксически действителен сам по себе, но, поскольку он дает другой результат, я думаю, что стоит упомянуть об этом здесь. В результате алгоритмически метод может возвращать неправильный (недопустимый) результат при копировании из Java в Groovy.

person tkruse    schedule 22.09.2014
comment
Равенство - определенно большая ловушка - person Craig Ringer; 07.11.2018

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

  • int def;
  • String s = "$$";
person Michael Borgwardt    schedule 26.03.2009

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

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

person Joe    schedule 03.02.2014

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

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

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

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

person DSoa    schedule 28.04.2014

Блоки нестатической инициализации:

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

ОБНОВЛЕНИЕ: это действительно действительный код Groovy.

person Jen S.    schedule 31.03.2009
comment
Черт? Я тоже не знал, что это действующая Java. - person Brandon Yarbrough; 10.04.2009
comment
Тестирование подтверждает, что он действительно запускается всякий раз, когда создается экземпляр класса. Странно. Чем больше ты знаешь. - person Brandon Yarbrough; 10.04.2009
comment
Это ДЕЙСТВИТЕЛЬНО работает в Groovy. По крайней мере, он работает как в Groovy 1.5.7, так и в 1.6. - person Peter Dolberg; 12.04.2009
comment
хм, у меня тоже работает. Я мог поклясться, что раньше это не сработало. Ну что ж, проголосовали против. - person Jen S.; 13.04.2009
comment
Стоит проголосовать за; некоторые люди не знали, что это работает на Java, и вы исправили, сказав, что это действительно работает и на Groovy. : 3 - person paulotorrens; 13.03.2014