Je me demande comment les variables marquées comme final sont interprétées par Groovy (dans 1.8.0, 1.8.1). Je sais que cela a du sens en Java et qu'il est possible d'améliorer les performances et -- bien sûr -- d'éviter les erreurs stupides. J'aimerais savoir si final peut aider le compilateur Java à optimiser un programme écrit en Groovy. Je me demande si les transformateurs Groovy préservent le caractère final des marques pour les variables.
Réponses
Trop de publicités?Il ne semble pas que groovyc
va intégrer les variables finales comme le fait javac. J'ai créé deux scripts scripts, l'un utilisant final et l'autre non :
final String message = "Hello World"
println message
String message = "Hello World"
println message
javap -c
a produit le même résultat pour les deux classes :
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
optimisé les astore
/ aload
:
Sans 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
Avec 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
Cela dit, si la performance est primordiale, Groovy est un mauvais choix pour commencer. L'inclusion de variables finales ne vous épargnera pas les frais généraux liés à l'utilisation de la réflexion pour les appels de méthodes.
En tant que Justin a dit Si les optimisations que le compilateur effectue pour les variables finales sont importantes pour vous, alors vous ne devriez pas utiliser Groovy.
Cependant, si les performances de Groovy sont suffisamment bonnes, il est toujours utile de marquer les variables comme finales pour deux raisons :
-
Protéger les invariants de votre classe, c'est-à-dire s'assurer qu'une valeur ne peut pas être modifiée après la construction de l'objet. Java l'impose à la compilation, Groovy ne l'impose qu'à l'exécution, mais c'est mieux que d'autoriser silencieusement la modification d'une valeur immuable.
-
Documentation. Les utilisateurs de votre classe peuvent facilement voir quelles sont les valeurs qu'ils sont autorisés à modifier