Имеет ли смысл помечать переменную как final в groovy? - PullRequest
13 голосов
/ 24 августа 2011

Интересно, как переменные, помеченные как final , интерпретируются Groovy (в 1.8.0, 1.8.1). Я знаю, что это имеет смысл в Java, и это позволяет улучшить производительность и - конечно же - помочь избежать глупых ошибок. Я хотел бы узнать, может ли final помочь компилятору java оптимизировать программу, написанную на Groovy. Интересно, сохраняют ли Groovy-преобразователи маркировку final для переменных.

Ответы [ 3 ]

17 голосов
/ 24 августа 2011

Похоже, что groovyc не будет указывать конечные переменные так, как это делает javac. Я создал два тестовых сценария, один из которых был финальным, а другой нет:

final String message = "Hello World"
println message
String message = "Hello World"
println message

javap -c выдает одинаковый результат для обоих классов:

   0:   invokestatic    #18; //Method $getCallSiteArray:()[Lorg/codehaus/groovy/runtime/callsite/CallSite;
   3:   astore_1
   4:   ldc #58; //String Hello World
   6:   astore_2
   7:   aload_1
   8:   ldc #59; //int 1
   10:  aaload
   11:  aload_0
   12:  aload_2
   13:  invokeinterface #63,  3; //InterfaceMethod org/codehaus/groovy/runtime/callsite/CallSite.callCurrent:(Lgroovy/lang/GroovyObject;Ljava/lang/Object;)Ljava/lang/Object;
   18:  areturn
   19:  nop

javac оптимизировано для astore / aload:

Без final:

   0:   ldc #2; //String Hello World
   2:   astore_1
   3:   getstatic   #3; //Field java/lang/System.out:Ljava/io/PrintStream;
   6:   aload_1
   7:   invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   10:  return

С final:

   0:   getstatic   #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   3:   ldc #3; //String Hello World
   5:   invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   8:   return

Все это говорит о том, что если производительность имеет первостепенное значение, Groovy - плохой выбор для начала. Заключение заключительных переменных не избавит вас от необходимости использования отражения для вызовов методов.

12 голосов
/ 25 августа 2011

Как и Джастин сказал , если оптимизация, которую выполняет компилятор для конечных переменных, важна для вас, то вам не следует использовать Groovy.

Однако, если производительность Groovy достаточно хорошая, тогда все равно полезно помечать переменные как final по двум причинам:

  • Защита инвариантов вашего класса, то есть проверка того, что значение не может быть изменено после построения объекта. Java применяет это во время компиляции, Groovy применяет это только во время выполнения, но это лучше, чем безмолвное изменение неизменяемого значения

  • Документация. Пользователи вашего класса могут легко увидеть, какие значения им разрешено изменять

3 голосов
/ 27 августа 2011

пока нет.но это может произойти в будущем, поэтому я все еще отмечу их при необходимости.

https://issues.apache.org/jira/browse/GROOVY-1628

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