基础
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 2平台中新增加的许多安全结构方面的措施,同时对Java安全性的实施提出了使用指导,描绘了如何定制、扩展和精化安全结构以及...
本文介绍了Java的可移植性特点,包括字节码、Java虚拟机(JVM)和跨平台开发。同时,提供了相应的Java示例代码。 内容概要 本文档涵盖以下内容: 字节码的概念和作用 Java虚拟机(JVM)的作用和重要性 跨平台开发...
基础概念与常识 Java 语言有哪些特点? JVM vs JDK vs JRE JVM JDK 和 JRE 什么是字节码?采用字节码的好处是什么? 为什么说 Java 语言“编译与解释并存”? Oracle JDK vs OpenJDK Java 和 C++ 的区别? 基本语法 字符...
JAVA入门基础篇,适合于初学者.第一章 Java语言入门 授课内容: ...7.分析Java运行过程,再次讲解Jvm、字节码等概念 8.简单介绍JSP技术 作业: 1. 配置环境变量 2. 完成第一个Java程序的编译及运行
2023最新整理,java基础面试题,涵盖基础概念与常识、基本语法、基本数据类型、面向对象基础、Java常见类、异常、泛型、反射、注解、SPI、序列化和发序列化等知识点,目录清洗,共有近60个基础知识面试题以及详细...
= 保镖 = 字节码校验器 = ByteCode Verifier = 翻译 = 解释执行器 = Interfreter 2:安全 健壮 电力 电信 银行 都会有限考虑使用java实现 3:免费 开源 4:简单 语法简单:c++-- (取其精华 去其糟粕) ...
- 字节码的解释和执行过程; - 使用Java反射机制获取类信息的方法; 阅读建议: - 在阅读过程中,请结合实际代码运行,加深对概念和原理的理解。 - 尝试修改示例代码,观察结果的变化,以加强对原理的掌握。 - ...
《java程序设计》课程的题库资料,由贺州学院整理,可供学生期末课程复习使用,也可以供相关...10. Java是面向对象的语言,对象是客观事物,对象与之是一一对应,它是很具体的概念。( ) 答案:× [考点范围] JAVA简介
Java基础知识 Java是一种面向对象的编程语言,它支持封装、继承和多态等面向对象的基本概念。Java具有静态类型检查机制,需要在编译时指定变量的类型。Java提供了基本数据类型,如int、double、float等,也支持引用...
----------------------------------- Android 编程基础 1 封面----------------------------------- Android 编程基础 2 开放手机联盟 --Open --Open --Open --Open Handset Handset Handset Handset Alliance ...
Java基础部分 7 1、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 7 2、Java有没有goto? 7 3、说说&和&&的区别。 8 4、在JAVA中如何跳出当前的多重嵌套循环? 8 5、switch语句能否作用在byte...
一、JAVA SE基础 1、开发语言基本包括:数据类型、循环控制语句、数组、方法 2、面向对象:最终是面向接口编程的,封装...JAVA提供多线程、提供动态下载程序代码的机制、安全性,它的操作以字节码(class)文件形式保存
这些源代码可以被Java编译器编译成字节码,然后在Java虚拟机(JVM)上运行。Java是一种面向对象的编程语言,广泛应用于各种应用场景,从桌面应用到大型企业级应用,从移动应用到嵌入式系统。 适合人群:大学生、...
这些源代码可以被Java编译器编译成字节码,然后在Java虚拟机(JVM)上运行。Java是一种面向对象的编程语言,广泛应用于各种应用场景,从桌面应用到大型企业级应用,从移动应用到嵌入式系统。 适合人群:大学生、...
这些源代码可以被Java编译器编译成字节码,然后在Java虚拟机(JVM)上运行。Java是一种面向对象的编程语言,广泛应用于各种应用场景,从桌面应用到大型企业级应用,从移动应用到嵌入式系统。 适合人群:大学生、...
这些源代码可以被Java编译器编译成字节码,然后在Java虚拟机(JVM)上运行。Java是一种面向对象的编程语言,广泛应用于各种应用场景,从桌面应用到大型企业级应用,从移动应用到嵌入式系统。 适合人群:大学生、...
这些源代码可以被Java编译器编译成字节码,然后在Java虚拟机(JVM)上运行。Java是一种面向对象的编程语言,广泛应用于各种应用场景,从桌面应用到大型企业级应用,从移动应用到嵌入式系统。 适合人群:大学生、...