JD-Core es un decompilador de clases Java que destaca, entre otras cosas, porque, a diferencia del popular Jad, soporta algunas de las novedades más importantes introducidas en Java 5, como los generics o el tipo enum. Este decompilador cuenta con dos interfaces, una aplicación standalone llamada JD-GUI y un plugin para Eclipse llamado JD-Eclipse.
Vamos a crear una pequeña clase de ejemplo para demostrar su funcionamiento.
import java.util.EnumSet;
public class Ejemplo {
enum Dia {
LUNES, MARTES, MIERCOLES, JUEVES, VIERNES, SABADO, DOMINGO
}
public static void main(String[] args) {
for (Dia dia : EnumSet.allOf(Dia.class))
System.out.println(dia);
}
}
Si abrimos la vista de navegador en Eclipse (Window -> Show View -> Navigator) y hacemos doble clic sobre el archivo que representa a nuestra clase compilada en la carpeta bin, se lanzará el visor de clases, mostrando el bytcode de la clase. También podemos utilizar la herramienta javap, incluída en el JDK:
javap -c Ejemplo
El bytecode de nuestra clase tiene el siguiente aspecto:
// Compiled from Ejemplo.java (version 1.6 : 50.0, super bit)
public class Ejemplo {
// Method descriptor #6 ()V
// Stack: 1, Locals: 1
public Ejemplo();
0 aload_0 [this]
1 invokespecial java.lang.Object() [8]
4 return
Line numbers:
[pc: 0, line: 3]
Local variable table:
[pc: 0, pc: 5] local: this index: 0 type: Ejemplo
// Method descriptor #15 ([Ljava/lang/String;)V
// Stack: 2, Locals: 3
public static void main(java.lang.String[] args);
0 ldc <Class Ejemplo$Dia> [16]
2 invokestatic java.util.EnumSet.allOf(java.lang.Class) : java.util.EnumSet [18]
5 invokevirtual java.util.EnumSet.iterator() : java.util.Iterator [24]
8 astore_2
9 goto 29
12 aload_2
13 invokeinterface java.util.Iterator.next() : java.lang.Object [28] [nargs: 1]
18 checkcast Ejemplo$Dia [16]
21 astore_1 [dia]
22 getstatic java.lang.System.out : java.io.PrintStream [34]
25 aload_1 [dia]
26 invokevirtual java.io.PrintStream.println(java.lang.Object) : void [40]
29 aload_2
30 invokeinterface java.util.Iterator.hasNext() : boolean [46] [nargs: 1]
35 ifne 12
38 return
Line numbers:
[pc: 0, line: 9]
[pc: 22, line: 10]
[pc: 29, line: 9]
[pc: 38, line: 11]
Local variable table:
[pc: 0, pc: 39] local: args index: 0 type: java.lang.String[]
[pc: 22, pc: 29] local: dia index: 1 type: Ejemplo.Dia
Stack map table: number of frames 2
[pc: 12, full, stack: {}, locals: {java.lang.String[], _, java.util.Iterator}]
[pc: 29, same]
Inner classes:
[inner class info: #16 Ejemplo$Dia, outer class info: #1 Ejemplo
inner name: #59 Dia, accessflags: 16408 static final]
}
Como vemos en realidad el bucle for each se convierte en un bucle que utiliza un iterador.
Si usamos el decompilador jad el resultado será:
import java.io.PrintStream;
import java.util.EnumSet;
import java.util.Iterator;
public class Ejemplo {
static final class Dia extends Enum {
public static Dia[] values() {
Dia adia[];
int i;
Dia adia1[];
System.arraycopy(adia = ENUM$VALUES, 0,
adia1 = new Dia[i = adia.length], 0, i);
return adia1;
}
public static Dia valueOf(String s) {
return (Dia) Enum.valueOf(Ejemplo$Dia, s);
}
public static final Dia LUNES;
public static final Dia MARTES;
public static final Dia MIERCOLES;
public static final Dia JUEVES;
public static final Dia VIERNES;
public static final Dia SABADO;
public static final Dia DOMINGO;
private static final Dia ENUM$VALUES[];
static {
LUNES = new Dia("LUNES", 0);
MARTES = new Dia("MARTES", 1);
MIERCOLES = new Dia("MIERCOLES", 2);
JUEVES = new Dia("JUEVES", 3);
VIERNES = new Dia("VIERNES", 4);
SABADO = new Dia("SABADO", 5);
DOMINGO = new Dia("DOMINGO", 6);
ENUM$VALUES = (new Dia[] { LUNES, MARTES, MIERCOLES, JUEVES,
VIERNES, SABADO, DOMINGO });
}
private Dia(String s, int i) {
super(s, i);
}
}
public Ejemplo() {
}
public static void main(String args[]) {
Dia dia;
for (Iterator iterator = EnumSet.allOf(Ejemplo$Dia).iterator(); iterator
.hasNext(); System.out.println(dia))
dia = (Dia) iterator.next();
}
}
que como vemos no está demasiado mal, pero dista bastante del original.
Por último este es el resultado de JD-GUI:
import java.io.PrintStream;
import java.util.EnumSet;
import java.util.Iterator;
public class Ejemplo {
public static void main(String[] args) {
for (Iterator localIterator = EnumSet.allOf(Ejemplo.Dia.class)
.iterator(); localIterator.hasNext();) {
Ejemplo.Dia dia = (Ejemplo.Dia) localIterator.next();
System.out.println(dia);
}
}
static enum Dia {
LUNES, MARTES, MIERCOLES, JUEVES, VIERNES, SABADO, DOMINGO;
}
}

La verdad es que es algo muy útil, que no sabes en que momento lo vas a necesitar.
Programa a tener en mente xD
yo lo he usado muchas veces para decompilar las clases que vienen en la EBS de Oracle! te salva la vida 😉
Pingback: JD-GUI, decompilar una clase Java « Ubuntu Life
Pingback: 100 programas gratis « Bichotoblog
estaa bueno
Qué tan ilegal o legal es usar esta aplicación??
Gracias, es una herramienta necesaria para decopilar clases realizadas en otros entornos y usarlos para eclipse, por citar un ejemplo.
Abrazox