Действительный код Java, который НЕ является допустимым кодом Groovy? - PullRequest
24 голосов
/ 27 марта 2009

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

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

Обновление:

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

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

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

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

Ответы [ 8 ]

33 голосов
/ 11 апреля 2009

Вот список элементов, которые действительны для 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();

** Класс на enum в 1.6 (действительно в более поздних версиях Groovy) **

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

Do loop

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

Равенство

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

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

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

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

12 голосов
/ 27 марта 2009

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

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 голосов
/ 27 июня 2010

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

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

def x=new Object[5][2]; // this works
2 голосов
/ 22 сентября 2014

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

Помимо действительного кода Java, который недопустим в Groovy, вам также следует остерегаться кода, действительного как в Java, так и в Groovy, но в Groovy он дает разные результаты. Очевидными примерами являются символьные литералы и строки 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.

1 голос
/ 28 апреля 2014

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

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

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

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

1 голос
/ 04 февраля 2014

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

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

1 голос
/ 27 марта 2009

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

  • int def;
  • String s = "$$";
0 голосов
/ 31 марта 2009

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...