Dans le cas du bytecode Java, ce n'est pas toujours possible car certaines contraintes n'existent pas dans le bytecode mais existent dans le Java.
Par exemple, le fait que la première instruction d'un constructeur doivent être l'appel au constructeur de la super classe n'existe pas dans le bytecode. Scala utilisait ça par moment.
De même dans la gestion des exceptions, Java est connu pour ses checked exceptions qui font partie de l'interface, cependant c'est une contrainte purement au niveau du source, et pas dans le bytecode. Même si les checked exceptions se retrouvent dans l'interface du bytecode, elles ne sont explicitement pas vérifiées. Scala n'a pas ce concept. Pour avoir du bytecode Scala avec exceptions décompilé avec qui recompile en Java, il faut réinférer toutes les exceptions qui ne sont pas des RuntimeException pour les ajouter dans l'interface. Bref, ce n'est pas direct.
Scala génère aussi des suites d'instructions bytecode qui peuvent ne correspondre à aucune construction en Java. Par exemple les boucles en Java sont compilées d'une certaine manière et Scala les transforme différemment, notamment dû au fait qu'un for scala se traduit en des appels à des méthodes du style map et flatMap. Le compilateur Scala fait aussi de l'optimisation des récursions terminales triviales, je ne suis pas sûr de comment un décompilateur Java peut retraduire ça, si le code généré correspond à comment le compilateur Java compilerait un while.
Il y a plein de raisons pour lesquelles il est impossible de ressortir du Java à partir de bytecode, la JVM étant moins restrictif que le langage Java. Les obfuscateurs de bytecode jouent là dessus, en réorganisant les instructions pour sans changer la sémantique mais en créant des séquences qui sont inatteignables depuis le Java.
L'avantage du bytecode est surtout d'être encore assez abstrait pour être portable, il n'a pas besoin de coller au langage source. Surtout pour la JVM maintenant qui fait tourner du bytecode généré depuis plein de langages très différents (java, scala, closure, groovy, python, ruby, ocaml, ...). Par exemple le bytecode OCaml est assez loin du langage source, voir les instructions
[^] # Re: Erreurs dans l'article sur Scala, Groovy et Java
Posté par Lucas . En réponse à la dépêche Sortie de Haxe 3.2.0. Évalué à 4.
Dans le cas du bytecode Java, ce n'est pas toujours possible car certaines contraintes n'existent pas dans le bytecode mais existent dans le Java.
Par exemple, le fait que la première instruction d'un constructeur doivent être l'appel au constructeur de la super classe n'existe pas dans le bytecode. Scala utilisait ça par moment.
De même dans la gestion des exceptions, Java est connu pour ses checked exceptions qui font partie de l'interface, cependant c'est une contrainte purement au niveau du source, et pas dans le bytecode. Même si les checked exceptions se retrouvent dans l'interface du bytecode, elles ne sont explicitement pas vérifiées. Scala n'a pas ce concept. Pour avoir du bytecode Scala avec exceptions décompilé avec qui recompile en Java, il faut réinférer toutes les exceptions qui ne sont pas des
RuntimeExceptionpour les ajouter dans l'interface. Bref, ce n'est pas direct.Scala génère aussi des suites d'instructions bytecode qui peuvent ne correspondre à aucune construction en Java. Par exemple les boucles en Java sont compilées d'une certaine manière et Scala les transforme différemment, notamment dû au fait qu'un
forscala se traduit en des appels à des méthodes du stylemapetflatMap. Le compilateur Scala fait aussi de l'optimisation des récursions terminales triviales, je ne suis pas sûr de comment un décompilateur Java peut retraduire ça, si le code généré correspond à comment le compilateur Java compilerait un while.Il y a plein de raisons pour lesquelles il est impossible de ressortir du Java à partir de bytecode, la JVM étant moins restrictif que le langage Java. Les obfuscateurs de bytecode jouent là dessus, en réorganisant les instructions pour sans changer la sémantique mais en créant des séquences qui sont inatteignables depuis le Java.
L'avantage du bytecode est surtout d'être encore assez abstrait pour être portable, il n'a pas besoin de coller au langage source. Surtout pour la JVM maintenant qui fait tourner du bytecode généré depuis plein de langages très différents (java, scala, closure, groovy, python, ruby, ocaml, ...). Par exemple le bytecode OCaml est assez loin du langage source, voir les instructions