capacités d’élimination de code javac

J’ai du mal à trouver des informations sur les capacités d’élimination de code de javac :

J’ai lu que si vous aviez quelque chose comme ce qui suit, la déclaration if sera éliminée:

 static final boolean DEBUG = false; if (DEBUG) System.out.println("Hello World!"); // will be removed 

Mais que dire de ceci, par exemple:

 static final int VALUE = 3; if (VALUE > 9) System.out.println("VALUE > 9 ???"); // will this be removed? 

Ou ca:

 static final SomeEnum VALUE = SomeEnum.FOO; if (VALUE==SomeEnum.BAR) System.out.println("Bar???"); // will this be removed? 

Comme il est très difficile / impossible d’parsingr un programme pour trouver tout le code mort (probablement semblable au problème d’arrêt), j’imagine qu’il n’ya que quelques constructions bien définies (comme le premier exemple ci-dessus), que javac reconnaîtra et enlever de manière fiable. Existe-t-il une liste complète de ces constructions?

Assylias semble avoir trouvé la réponse (laissez-moi juste tout mettre ensemble):

Le chapitre “14.21. Instructions inaccessibles” du JLS précise qu’en général, toute instruction inaccessible dans le code est considérée comme une erreur de compilation, la seule exception étant un traitement spécial des instructions if permettant spécifiquement la compilation conditionnelle. .

Par conséquent, la seule construction pouvant entraîner une élimination de code (si le compilateur choisit de le faire!) Est la suivante:

 if (comstackTimeConstantExpression) { doThis(); // may be removed if comstackTimeConstantExpression == false; } else { doThat(); // may be removed if comstackTimeConstantExpression == true; } 

(la partie else est facultative, bien sûr)

Toutes les autres constructions permettant l’élimination de code, comme par exemple while (false) ... , sont interdites et génèrent une erreur de compilation au lieu de générer une compilation conditionnelle.

La définition de ce qui constitue une comstackTimeConstantExpression acceptable se trouve au chapitre “15.28. Expressions constantes” du JLS . Une autre grande page avec d’autres exemples est disponible ici: Comstack Time Constants in Java

Remarque: Un compilateur n’est pas tenu de supprimer les sections “inaccessibles” d’un if -stament. javac semble le faire de manière fiable, mais d’autres compilateurs ne le peuvent pas. Le seul moyen de savoir avec certitude est de vérifier le résultat via une décompilation, par exemple en utilisant javap -c comme suggéré par Jon Skeet.

J’ai effectué quelques tests et il semble (logiquement) que javac supprime le code si la condition est une expression constante évaluée à false.

En résumé, les expressions constantes sont des expressions qui utilisent uniquement des constantes en tant qu’opérandes, à savoir des primitives, des littéraux de chaîne et des primitives final ou des variables Ssortingngs initialisées avec une valeur constante.

Notez que cela dépend du compilateur car le JLS ne force pas le compilateur à être aussi intelligent que celui expliqué au bas de 14.21 :

Un compilateur optimiseur peut se rendre compte que l’instruction x = 3; ne sera jamais exécuté et peut choisir d’omettre le code de cette instruction dans le fichier de classe généré.

Je vois que pour le 2ème exemple, il est également supprimé

c’était ma classe

 public class Test { public static void main(Ssortingng[] args) throws Exception{ final int VALUE = 3; if (VALUE > 9) System.out.println("VALUE > 9 ???"); } } 

et c’est la version décompilée

 Comstackd from "Test.java" public class Test extends java.lang.Object{ public Test(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."":()V 4: return public static void main(java.lang.Ssortingng[]) throws java.lang.Exception; Code: 0: return } 

Je suppose que cela dépend de la mise en œuvre (Oracle, IBM, …).

Si vous êtes intéressé par la version d’Oracle, le projet OpenJDK constitue un bon sharepoint départ pour rechercher des ressources: http://openjdk.java.net/groups/comstackr/