简体   繁体   English

了解Java字节代码

[英]Understanding Java Byte Code

Often I am stuck with a java class file with no source and I am trying to understand the problem I have at hand. 我经常遇到一个没有源代码的java类文件,我试图理解我手边的问题。

Note a decompiler is useful but not sufficient in all situation... 请注意,反编译器很有用但在所有情况下都不够......

I have two question 我有两个问题

  1. What tools are available to view java byte code (preferably available from the linux command line ) 有哪些工具可用于查看java字节代码(最好从linux命令行获得)
  2. What are good references to get familiar with java byte code syntax 熟悉java字节码语法有什么好的参考

Rather than looking directly at the Java bytecode, which will require familiarity with the Java virtual machine and its operations, one could try to use a Java decompiling utility. 可以尝试使用Java反编译实用程序,而不是直接查看需要熟悉Java虚拟机及其操作的Java字节码。 A decompiler will attempt to create a java source file from the specified class file. 反编译器将尝试从指定的class文件创建java源文件。

The How do I “decompile” Java class files? 我如何“反编译”Java类文件? is a related question which would be informative for finding out how to decompile Java class files. 是一个相关的问题,可以提供有关如何反编译Java class文件的信息。

That said, one could use the javap command which is part of the JDK in order to disassemble Java class files. 也就是说,可以使用javap命令,它是JDK的一部分,以便反汇编Java class文件。 The output of javap will be the Java bytecode contained in the class files. javap的输出将是class文件中包含的Java字节码。 But do be warned that the bytecode does not resemble the Java source code at all. 但请注意,字节码根本不像Java源代码。

The definite source for learning about the Java bytecode and the Java Virtual Machine itself would be The Java Virtual Machine Specification, Second Edition . 学习Java字节码和Java虚拟机本身的明确来源是Java虚拟机规范,第二版 In particular, Chapter 6: The Java Virtual Machine Instruction Set has an index of all the bytecode instructions. 特别是, 第6章:Java虚拟机指令集具有所有字节码指令的索引。

To view bytecode instruction of class files, use the javap -v command, the same way as if you run a java program, specifying classpath (if necessary) and the class name. 要查看类文件的字节码指令,请使用javap -v命令,就像运行java程序一样,指定classpath(如果需要)和类名。

Example: 例:

javap -v com.company.package.MainClass

About the bytecode instruction set, Instruction Set Summary 关于字节码指令集, 指令集汇总

Fernflower is an analytical decompiler, so it will decompile classes to a readable java code instead of bytecodes. Fernflower是一个分析反编译器,因此它会将类反编译为可读的java代码而不是字节码。 It's much more usefull when you want to understand how code works. 当您想要了解代码的工作原理时,它会更有用。

If you have a class and no source code, but you have a bug, you can do one of two basic things: 如果你有一个类而没有源代码,但是你有一个bug,你可以做以下两件事之一:

  1. Decompile, fix the bug and recreate the jar file. 反编译,修复错误并重新创建jar文件。 I have done this before, but sysadmins are leery about putting that into production. 我之前已经这样做了,但是系统管理员对于将其投入生产非常谨慎。
  2. Write unit tests for the class, determine what causes the bug, report the bug with the unit tests and wait for it to be fixed. 编写类的单元测试,确定导致错误的原因,通过单元测试报告错误并等待修复。

    (2) is generally the one that sysadmins, in my experience, prefer. 根据我的经验,(2)通常是系统管理员喜欢的那个。

    If you go with (2) then, in the meantime, since you know what causes the bug, you can either not allow that input to go to the class, to prevent a problem, or be prepared to properly handle it when the error happens. 如果你跟(2)一起去,那么,在此期间,既然你知道导致bug的原因,你可以不允许该输入进入类,以防止出现问题,或者准备好在错误发生时正确处理它。

    You can also use AspectJ to inject code into the problem class and change the behavior of the method without actually recompiling. 您还可以使用AspectJ将代码注入问题类,并在不实际重新编译的情况下更改方法的行为。 I think this may be the preferable option, as you can change it for all code that may call the function, without worrying about teaching everyone about the problem. 我认为这可能是更好的选择,因为您可以为所有可能调用该函数的代码更改它,而不必担心教会每个人关于该问题。

    If you learn to read the bytecode instructions, what will you do to solve the problem? 如果您学习阅读字节码指令,您将如何解决问题?

I have two question 我有两个问题

1) What tools are available to view java byte code (preferably available from the linux command line ) 1)有哪些工具可用于查看java字节代码(最好从linux命令行获得)

The javap tool (with the -c option) will disassemble a bytecode file. javap工具(带-c选项)将反汇编字节码文件。 It runs from the command line, and is supplied as part of the Java SDK. 它从命令行运行,并作为Java SDK的一部分提供。

2) What are good references to get familiar with java byte code syntax 2)熟悉java字节码语法有什么好的参考

The javap tool uses the same syntax as is used in the JVM specification, and the JVM spec is naturally the definitive source. javap工具使用与JVM规范中使用的语法相同的语法,JVM规范自然是权威源。 I also spotted "Inside the Java Virtual Machine" by Bill Venners. 我还发现了Bill Venners的“Inside the Java Virtual Machine”。 I've never read it, and it looks like it might be out of print. 我从来没有看过它,看起来它可能已经绝版了。

The actual (textual) syntax is simple and self explanatory ... assuming that you have a reference that explains what the bytecodes do, and that you are moderately familiar with reading code at this level. 实际(文本)语法是简单且自我解释的......假设您有一个引用来解释字节码的作用,并且您熟悉在此级别读取代码。 But it is likely to be easier to read the output of a decompiler, even if the bytecodes has been fed through an obfuscator. 但是,即使字节码已通过混淆器提供,也可能更容易读取反编译器的输出。

You might find the Eclipse Byte Code Outline plugin useful: 您可能会发现Eclipse Byte Code Outline插件很有用:

http://andrei.gmxhome.de/bytecode/index.html http://andrei.gmxhome.de/bytecode/index.html

I have not used it myself - just seen it mentioned in passing. 我自己没有用过它 - 只是看到它顺便提到了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM