Действительный код 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
Результаты в литерале примитивного типа: байт не может использоваться как имя метода