本章,我将采用一个例子来讲解class文件结构,并介绍jvm是如何操作分配内存的。
我们新建一个类,设置了两个比较简单的例子,就是创建String的,因为这个类对象处理起来有点特殊,所以拿过来作为例子来讲解
public class StringKnowledgeTest { public String getName(){ String fengfuName="fengfu"; return fengfuName; } public String getnewName(){ String zhaoff=new String("zhaoff");//这语句,一共生成了几个对象 return zhaoff; } }
使用javap -verbose StringKnowledgeTest 查看类结构
常量池为:
const #1 = class #2; // knowledgeTest/StringKnowledgeTest const #2 = Asciz knowledgeTest/StringKnowledgeTest; const #3 = class #4; // java/lang/Object const #4 = Asciz java/lang/Object; const #5 = Asciz ; const #6 = Asciz ()V; const #7 = Asciz Code; const #8 = Method #3.#9; // java/lang/Object."":()V const #9 = NameAndType #5:#6;// "":()V const #10 = Asciz LineNumberTable; const #11 = Asciz LocalVariableTable; const #12 = Asciz this; const #13 = Asciz LknowledgeTest/StringKnowledgeTest;; const #14 = Asciz getName; const #15 = Asciz ()Ljava/lang/String;; const #16 = String #17; // fengfu const #17 = Asciz fengfu; const #18 = Asciz fengfuName; const #19 = Asciz Ljava/lang/String;; const #20 = Asciz getnewName; const #21 = class #22; // java/lang/String const #22 = Asciz java/lang/String; const #23 = String #24; // zhaoff const #24 = Asciz zhaoff; const #25 = Method #21.#26; // java/lang/String."":(Ljava/lang/String;)V const #26 = NameAndType #5:#27;// "":(Ljava/lang/String;)V const #27 = Asciz (Ljava/lang/String;)V; const #28 = Asciz SourceFile; const #29 = Asciz StringKnowledgeTest.java;
从常量池中第17个来看,方法getName中的String "fengfu"在经过编译后,就会被保存到常量池中,方法getnewName也是这样,"zhaoff"经过编译后,会放入class常量池中,并最终内存方法区中。
getName对应的jvm指令为:
public java.lang.String getName(); Code: Stack=1, Locals=2, Args_size=1 0: ldc #16; //String fengfu //该操作为:从运行时常量池中提取数据推入操作数栈,reference类型则为推入reference类型 2: astore_1 //该操作为:将一个reference类型数据保存到局部变量表 3: aload_1 //该操作为:从局部变量表中读取一个reference类型到操作数栈 4: areturn //从操作数栈返回一个reference数据,结束方法 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LknowledgeTest/StringKnowledgeTest; 3 2 1 fengfuName Ljava/lang/String;
jvm指令的整个过程,都是操作局部变量表与操作数栈,通过出入栈方式来完成该方法。
本过程一个只生成了一个字符串常量,并且在编译后,就保存在了class文件常量池中。
执行过程中局部变量表和操作数栈的变化如下:
getnewName方法对应的jvm指令如下:
public java.lang.String getnewName(); Code: Stack=3, Locals=2, Args_size=1 0: new #21; //class java/lang/String //new 一个 String 并将该String的reference压入操作数栈 3: dup //复制操作数栈栈顶的值,并压入操作数栈 4: ldc #23; //String zhaoff //该操作为:从运行时常量池中提取数据推入操作数栈,reference类型则为推入reference类型 6: invokespecial #25; //Method java/lang/String."":(Ljava/lang/String;)V //调用String 构造函数 9: astore_1 //该操作为:将一个reference类型数据保存到局部变量表 10: aload_1 //该操作为:从局部变量表中读取一个reference类型到操作数栈 11: areturn //从操作数栈返回一个reference数据,结束方法 LocalVariableTable: Start Length Slot Name Signature 0 12 0 this LknowledgeTest/StringKnowledgeTest; 10 2 1 zhaoff Ljava/lang/String;
执行过程中局部变量表和操作数栈的变化如下:
总结,从上面可以看出来,new String("abc") 产生了两个对象,要比String test="ABC"jvm指令要复杂,而且产生的对象也要多一个。第二种方式虽然产生了一个对象,但该对象位于常量池中,后期再次使用到"ABC"时,会服用常量池中的该变量。
相关推荐
Java Class文件是Java源代码经过编译器处理后的二进制形式,它们包含了程序的结构信息,如类、接口、变量、方法等定义。在Java开发过程中,有时我们需要查看或分析这些Class文件,以理解程序运行原理、调试或逆向...
### Java反编译工具:将.class文件转换为.java文件 #### 概述 在软件开发领域,有时我们可能需要分析第三方库或者开源项目的内部结构,这时就需要借助于反编译工具来帮助我们阅读和理解其源码。Java作为一种广泛...
需要注意的是,修改.class文件通常不是常规的开发流程,它可能用于调试、修复bug或研究已有的闭源软件。在进行这类操作时,必须遵守版权法,确保你有权利访问和修改这些代码。 总结来说,"电脑java class文件查看与...
2. **JD-GUI**:由JetBrains开发,它提供了一个图形界面,可以直接打开.class文件并显示对应的源代码。它适合快速查看代码,但不支持编辑或保存反编译的结果。 3. **Procyon**:这是另一个开源项目,它不仅是一个反...
Java class文件是Java程序编译后的二进制代码,它包含了类、方法、变量等信息。但是,由于class文件是以机器可读的形式存在,对于人类来说并不直观。这时,我们就需要借助于反编译工具来将class文件转换回源代码...
Java Class文件反编译工具是开发者在处理已编译的.class文件时的一种实用工具,它能够将二进制的Class文件转换回可读性更强的源代码格式,这对于理解和调试已封装的库或分析未知的Java程序至关重要。本文将详细介绍...
总的来说,ClassFinal作为一款Java class文件安全加密工具,为开发者提供了一种简单、高效的代码保护方案,尤其适合于那些重视代码安全但又不想改动大量代码的企业级项目。其兼容性和易用性使其在Java开发领域具有...
总之,jd-gui.exe作为一款便捷的Java反编译工具,使得开发者能够轻松地查看和理解.class文件中的代码,对于学习、调试和研究都有着很大的帮助。在使用过程中,我们需要注意其局限性,如代码格式和注释可能不完整,...
"java class 文件查看神器"通常指的是用于查看和分析这些二进制类文件的工具,帮助开发者理解程序的内部结构和工作原理。在这种情况下,提到的“神器”很可能是`jd-gui`。 `jd-gui`是一款非常实用的Java反编译器,...
Java Class反编译工具是程序员在处理已编译的字节码文件时不可或缺的辅助工具。这类工具的主要功能是将`.class`文件转换回可读性强的`.java`源代码,帮助开发者理解或修改已有的Java程序,尤其在没有源代码的情况下...
Java Class文件是Java程序编译后的二进制代码,它包含了执行Java应用程序所需的方法和数据。反编译是将这些二进制代码转换回人类可读的源代码(类似于原始的.java文件)的过程。这对于理解已有的库或研究现有代码的...
JD-GUI是一款常用的Java反编译工具,它能将.class文件转换回接近原始的Java源代码形式,帮助用户理解和分析Java程序。 JD-GUI是一个图形用户界面应用程序,可以直接打开并显示单个Java类文件的源代码。它的界面简洁...
在IT领域,反编译是一种将已编译的字节码(如Java的.class文件)转换回源代码(如Java的.java文件)的过程。标题提到的"反编译软件"是一种工具,它允许用户查看和理解Java类文件的内部结构,即使原始的源代码不再...
Java反编译是将已编译的字节码(.class文件)转换回源代码(.java文件)的过程,这在需要查看或理解已丢失源代码的二进制类文件时非常有用。在这个领域,jd-gui是一款常用的开源工具。 jd-gui是一个图形用户界面的...
总的来说,Class文件反编译工具是Java开发者和研究人员的重要辅助工具,它使我们能在没有源代码的情况下理解和操作二进制的Java类文件,极大地扩展了我们的能力范围。在实际使用中,结合各种反编译器的特点和需求,...
Java反编译是一种技术,它允许开发者从已编译的.class文件中恢复原始的.java源代码。这在一些情况下非常有用,例如分析第三方库的内部实现、研究代码逻辑或者在丢失源代码时恢复源码。Java编译器将源代码转换成字节...
Java反编译工具是开发者和逆向工程人员在处理Java字节码时的重要工具,它能够将已编译的.class文件转换回可读性强的.java源代码文件。这对于理解类库的功能、学习代码实现或者在丢失源代码的情况下进行调试都极其...