javap是JDK中自带的反编译代码的利器jd-gui等工具也可以很方便的来实现反编译的功能,不过javap有jd-gui不具备的功能
工具/原料
方法/步骤
1先来看看脚本架java源代码Code:package chapter5;/** * Created by MyWorld on 2016/4/3. */public class ClassForDecompile { public static void main(String[] args) { Person person = new Student('Tom', 15); person.work(); }}class Person { protected final String name; protected final int age; public Person(String name, int age) { this.name = name; this.age = age; } protected void work() { System.out.println('Every person will work,for others or for self.'); }}class Student extends Person { public Student(String name, int age) { super(name, age); } @Override protected void work() { learn(); } private void learn() { System.out.println('I'm ' + name + ', age ' + age); }}
2使用javac编译ClassForDecompile.java文件命令:javac chapter5/ClassForDecompile.java
3有.class文件了,现在该javap出场了看看javap怎么用命令:javap --help
4看看正常的用法,把.class的文件反编译命令:javap -c chapter5/ClassForDecompile看看执行结果:Compiled from 'ClassForDecompile.java'public class chapter5.ClassForDecompile { public chapter5.ClassForDecompile(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object.'':()V 4: return public static void main(java.lang.String[]); Code: 0: new #2 // class chapter5/Student 3: dup 4: ldc #3 // String Tom 6: bipush 15 8: invokespecial #4 // Method chapter5/Student.'':(Ljava/lang/String;I)V 11: astore_1 12: aload_1 13: invokevirtual #5 // Method chapter5/Person.work:()V 16: return}
5如果不加参数c呢命令:javap chapter5/ClassForDecompile
6最后来看个jd-gui没有一个功能查看生成.class的jdk版本。这个信息在解决.class文件和jdk版本不一致时很有用命令:javap -v chapter5/ClassForDecompileOutput:Classfile /E:/java/JavaStudy/src/chapter5/ClassForDecompile.class Last modified 2016-4-3; size 416 bytes MD5 checksum accb0a72def6c8da33e5da929bee6dcc Compiled from 'ClassForDecompile.java'public class chapter5.ClassForDecompile minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPERConstant pool: #1 = Methodref #7.#16 // java/lang/Object.'':()V #2 = Class #17 // chapter5/Student #3 = String #18 // Tom #4 = Methodref #2.#19 // chapter5/Student.'':(Ljava/lang/String;I)V #5 = Methodref #20.#21 // chapter5/Person.work:()V #6 = Class #22 // chapter5/ClassForDecompile #7 = Class #23 // java/lang/Object #8 = Utf8 #9 = Utf8 ()V #10 = Utf8 Code #11 = Utf8 LineNumberTable #12 = Utf8 main #13 = Utf8 ([Ljava/lang/String;)V #14 = Utf8 SourceFile #15 = Utf8 ClassForDecompile.java #16 = NameAndType #8:#9 // '':()V #17 = Utf8 chapter5/Student #18 = Utf8 Tom #19 = NameAndType #8:#24 // '':(Ljava/lang/String;I)V #20 = Class #25 // chapter5/Person #21 = NameAndType #26:#9 // work:()V #22 = Utf8 chapter5/ClassForDecompile #23 = Utf8 java/lang/Object #24 = Utf8 (Ljava/lang/String;I)V #25 = Utf8 chapter5/Person #26 = Utf8 work{ public chapter5.ClassForDecompile(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object.'':()V 4: return LineNumberTable: line 6: 0 public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=4, locals=2, args_size=1 0: new #2 // class chapter5/Student 3: dup 4: ldc #3 // String Tom 6: bipush 15 8: invokespecial #4 // Method chapter5/Student.'':(Ljava/lang/String;I)V 11: astore_1 12: aload_1 13: invokevirtual #5 // Method chapter5/Person.work:()V 16: return LineNumberTable: line 8: 0 line 9: 12 line 10: 16}SourceFile: 'ClassForDecompile.java'
7最后执行下这个生成的.class文件吧命令:java chapter5/ClassForDecompile