基础
java源文件经过编译器编译后生成一个class文件,.class是二进制字节码文件,我们无法直接打开
查看里面的内容。但可以通过javap命令查看。
比如有一个D:coce\java\test\Test20.java文件
编译
通过javac 命令编译Test20.java文件
-- javac D:coce\java\test\Test20.java 会在 D:coce\java\test目录下生成一个Test20.class文件
如果想在D:根目录下生成Test20.class文件则执行
-- javac -d D:\ D:coce\java\test\Test20.java
执行
-- java D:coce\java\test\Test20
编译器将会直接解释执行Test20.class文件
-- java -cp D:coce\java\test Test20
编译器将会先找到D:coce\java\test文件夹;然后执行该文件夹下的Test20.class文件
字节码
D:coce\java\test>javap -c Test20
直接在控制台输出字节码文件。
D:coce\java\test>javap -c Test20 > Test20.bytecode
会在class目录下生成一个Test20.bytecode文件,用记事本打开就可以看到里面的内容了。
栈结构
每一个线程都有一个栈,栈由栈帧组成,线程每调用一个方法产生一个栈帧,栈帧由三部分组成操作数栈,局部变量数组和当前方法 所属类的 常量池的 引用( 帧数据)。
局部变量数组 存放方法的参数,一些局部变量等。大小在编译时候确定的。
操作数栈 是一个LIFO栈,两个动作组成压入和取出,也是在编译时确定的。
帧数据 ,java栈帧还包括了为了支持常量池,方法返回值和异常分发需要的数据,他们被保存在帧数据中。
源文件
package com.test;
public class Test1 {
public static void main(String[] args) {
Test1 t = new Test1();
t.sayHelloWord();
}
public void sayHelloWord() {
String h1 = new String ("HelloWord");
System.out.println(h1);
}
}
字节码文件
Compiled from "Test1.java"
public class com.test.Test1 extends java.lang.Object{
public com.test.Test1();
Code:
0: aload_0 // 将方法第一参数的地址推入栈顶,方法第一个参数就是this
1: invokespecial #8; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #1; //class com/test/Test1
3: dup
4: invokespecial #16; //Method "<init>":()V
7: astore_1
8: aload_1
9: invokevirtual #17; //Method sayHelloWord:()V
12: return
public void sayHelloWord();
Code:
0: new #23; //class java/lang/String
3: dup
4: ldc #25; //String HelloWord
6: invokespecial #27; //Method java/lang/String."<init>":(Ljava/lang/String;)V
9: astore_1
10: getstatic #30; //Field java/lang/System.out:Ljava/io/PrintStream;
13: aload_1
14: invokevirtual #36; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
17: return
}
说明:
1. ()V 标志该方法没有参数
2. #23 代表23号常量项
3. getstatic 调用静态对象
4. invokestatic:调用静态方法 ,在加载时期就确定调用方法的入口地址。
5. invokespecial:调用特定的方法,指的是不会根据对象实例的变化而变化的方法,
譬如调用构造方法,父类的方法等 ,在加载时期就确定调用方法的入口地址。
运行时,invokespecial选择方法基于引用的类型,而不是对象所属的类。
但invokevirtual则选择当前引用的对象。
6. invokevirtual:调用虚方法,具体调用的方法与调用的对象有关,如对象本身的方法。
在运行期确定才确定调用方法的入口。
7. invokeinterface:与invokevirtual一样,只是方法是在接口中声明的,在运行期确定才确定调用方法的入口。
8. 字节码前面都有些数字,0.3.4.6....等等。为什么不是连续的啊?如new指令,指令本身占一个字节(栈帧是以字节为单位的),参数占两个字节,所以dup指令从3开始。dup指令没有参数,只有指令本身占用一个字节,所以ldc指令从4开始。
public void sayHelloWord();
Code:
// 将当前对象的this压入操作栈,对于实例方法和构造函数的局部变量表 来说第一个入口总是这个“this”。
// 因为你需要访问一些实例中的方法和变量
0: new #23; //class java/lang/String
// 在堆中分配一个Sting类型的空间,用来存放String类型的对象。这是并没有存放实际的对象,只是开辟一个空间。
// 并把指向该堆的(地址)引用压入操作数栈。
3: dup
//复制操作数栈 栈顶数据,并把复制的数据压入操作数栈。当前操作数栈对该Stirng对象有两个相同的引用。
4: ldc #25; //String HelloWord
// 将常量池中HelloWord的(地址)引用压入操作数栈顶
6: invokespecial #27; //Method java/lang/String."<init>":(Ljava/lang/String;)V
// dup指令这里有两个引用,其中的一个引用调用String的构造方法,初始化对象;另一个相同的引用指向
// 初始化对象,前一个引用出栈。
// 调用的是String(String)这一个构造器。将ldc指令所找到的"HelloWord"的内容传入到new指令所开辟在堆中的字符串对象中,
// 然后将这个对象的引用压入操作数栈顶
9: astore_1
// 弹出操作数栈顶数据存放在局部变量区的第一个位置上。此时存放的是new指令创建出的,
// 已经被初始化的String对象的地址。
10: getstatic #30; //Field java/lang/System.out:Ljava/io/PrintStream;
// 调用静态对象out
13: aload_1
//把存放在局部变量表中索引1位置的对象引用压入操作栈,
14: invokevirtual #36; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
// 调用println方法
17: return
// 指向完毕,返回
}
分享到:
相关推荐
北京动力节点-Java编程零基础教程-011-Java语言概述-Java的工作原理-源文件及字节码文件.mp4 北京动力节点-Java编程零基础教程-012-Java语言概述-Java的工作原理-JVM分类.mp4 北京动力节点-Java编程零基础教程-...
本文将深入探讨Java字节码的基本概念、作用以及其在Java虚拟机(JVM)中的运行机制。 Java字节码是一种低级的、平台无关的指令集,它是Java源代码经过编译器处理后的产物。每条字节码指令通常只占用一个或两个字节...
JDK(Java Development Kit)包含了编译器javac和解释器java,它们分别用于将源代码编译成字节码和运行字节码。 通过这个“Java基础精品课01-初识java”,学习者将能够逐步建立起对Java编程的坚实基础,为后续深入...
Java 字节码是 Java 跨平台的基础,它使得 Java 程序可以在不同的平台上运行,而不需要重新编译。Java 字节码是平台无关性的基石,也是语言无关性的基础。 Class 文件结构是 Java 字节码的载体,它是一种特殊的二...
源代码是程序员用人类可读的语言编写的程序,需要通过Java编译器转化为字节码才能在Java虚拟机(JVM)上运行。在这些源代码中,我们可能会看到类、对象、方法、变量等基本概念的使用,以及面向对象编程的特性,如...
**JAVA字节码操作库 BCEL** BCEL(Byte Code Engineering Library)是Java开发的一个重要工具,主要用于处理Java字节码。它为开发者提供了一种深入理解与操作Java类文件的底层机制,允许分析、创建、修改和优化字节...
Java虚拟机(JVM)是Java程序运行的核心,它是一个抽象的计算机系统,负责执行Java字节码。在"【IT十八掌徐培成】Java基础第25天-06.JVM结构1"的课程中,我们将会深入探讨JVM的内部结构,了解它是如何使得Java具有跨...
本篇将详细讲解Java字节码的概念、用途以及JVM如何执行字节码。 首先,让我们理解什么是字节码。字节码是Java源代码在编译后的中间表示形式,它是平台无关的机器码,由一系列单字节的指令组成。每个Java方法都被...
在Java编程语言中,字节码(Bytecode)扮演着至关重要的角色,它是JVM(Java虚拟机)理解和执行程序的基础。"字节码实战"的主题深入探讨了字节码的概念、生成以及如何利用它来优化Java应用程序。下面将详细阐述相关...
Java注解、反射、字节码和类加载机制是Java编程中的核心概念,它们在实际开发中扮演着重要角色。让我们深入探讨这些知识点。 **Java注解(Annotation)**: Java注解是一种元数据,它提供了在编译时或运行时处理代码的...
Java基础是编程学习的核心部分,本总结主要涵盖了Java语言的基础概念和常见问题,适用于初学者和需要回顾基础知识的开发者。以下是对这些知识点的详细解释: 1. **基本数据类型**: - Java提供了八种基本数据类型...
3. `-source`和`-target`参数:分别指定源代码和目标代码的版本,确保编译出的字节码兼容特定的Java虚拟机(JVM)版本。 4. `-g`参数:控制是否生成调试信息,如行号、变量表等,这对于调试程序非常有用。 5. `-...
ASM是一个Java字节码操控和分析框架,它可以直接生成和分析类的二进制字节码,是许多Java和Android插桩工具的基础。通过这个插件,开发者无需深入理解复杂的字节码操作,就能实现AOP中的切面、通知等概念。 Gradle...
在传智播客的Java基础加强班中,学生将深入学习Java编程的基础知识,包括但不限于以下几个方面: 1. **Java语法格式**: - Java代码结构基于类,每个程序至少包含一个类,由`class`关键字定义。 - 大小写敏感是...
### JAVA基础入门知识点详解 #### 一、Java基础概述 - **标题**: "JAVA基础入门PPT" - **描述**: "JAVA初学者可以下载这个PPT,简单、实用,非常易于学习" 本PPT旨在为Java初学者提供一个简单易懂的学习材料,...
【Java基础知识点】 1. **Java的起源与特性** - Java是由SUN Microsystems公司(后被Oracle收购)开发的一种面向对象的编程语言。 - Java有三个主要版本:Java Standard Edition (JavaSE),用于桌面应用;Java ...
### Java基础知识笔记详细版-菜鸟翻阅必备 #### 一、Java概述 1. **Java语言发展史**: - Java由Sun Microsystems公司于1995年推出。 - 最初由James Gosling领导的设计团队开发,目标是用于家用电器的编程。 - ...
- **编译**:使用`javac`命令将.java源代码文件编译成.class字节码文件。 - **运行**:使用`java`命令执行main方法所在的类名。 3. **Java应用程序分类**: - **Java Application**:独立运行的应用,如桌面应用...
本文将深入探讨Java中的方法调用、值传递与引用传递,并通过字节码分析来进一步理解这些概念。 首先,我们来看方法调用。在Java中,方法是一组完成特定任务的代码块,可以通过方法名来调用执行。方法调用的基本语法...
知识点: 1. Java语言概论: ...以上是四川轻化工大学电子商务系使用的Java练习题中涉及的一些基础知识和概念,这些知识是Java编程和软件开发中的重要组成部分,对于理解和应用Java语言至关重要。