Java SE 基础知识
1. Java虚拟机(JVM)
Section titled “1. Java虚拟机(JVM)”
2. Java的加载与执行原理
Section titled “2. Java的加载与执行原理”2.1. 编译阶段
Section titled “2.1. 编译阶段”在编译阶段,Java程序员编写的.java源代码文件会经过javac编译器的处理。javac编译器会读取一个或多个.java源文件,对其进行词法分析、语法分析和语义分析等编译过程,最终将这些符合Java语法规则的源代码文件编译生成对应的.class字节码文件。这些.class文件包含了JVM能够理解和执行的字节码指令,而不是特定操作系统的机器码。
2.2. 运行阶段
Section titled “2.2. 运行阶段”运行阶段是在JVM(Java虚拟机)中完成的,这是Java实现”一次编译,到处运行”跨平台特性的核心机制。
2.2.1. 类加载过程
Section titled “2.2.1. 类加载过程”当使用java命令启动程序时,JVM首先通过ClassLoader(类加载器)来加载所需的.class文件。ClassLoader会根据CLASSPATH环境变量或命令行指定的路径来定位并加载.class文件。加载后的.class文件会经过以下步骤:
- 加载:将.class文件的二进制数据读入内存
- 链接:包括验证字节码的正确性和安全性、为静态变量分配内存并设置默认值等
- 初始化:执行静态初始化代码,为静态变量赋予正确的初始值
2.2.2. JVM执行过程
Section titled “2.2.2. JVM执行过程”加载完成后,JVM内部会进行一系列处理:
- 类加载验证:确保加载的字节码符合JVM规范,没有安全隐患
- 解释执行与即时编译:JVM既可以解释执行字节码,也可以通过JIT(即时编译器)将热点代码编译成本地机器码以提高执行效率
- 运行时数据管理:JVM管理程序运行所需的各种内存区域,包括堆、栈、方法区等
- 垃圾回收:自动管理内存,回收不再使用的对象
2.2.3. 与操作系统的交互
Section titled “2.2.3. 与操作系统的交互”JVM作为Java程序和底层操作系统之间的中间层,屏蔽了不同操作系统的差异。无论是Windows、Linux还是macOS,同一份.class字节码文件都可以在对应平台的JVM上运行。JVM会将字节码指令最终转换为特定操作系统的机器码,并通过操作系统调用硬件资源完成程序的实际执行。
这种设计使得Java程序具有良好的跨平台性,开发者只需编写一次代码,编译成字节码后就可以在任何安装了相应JVM的平台上运行,而无需针对不同操作系统重新编译。

3. JDK、JRE、JVM分别是什么?他们的关系是什么?
Section titled “3. JDK、JRE、JVM分别是什么?他们的关系是什么?”JDK(Java Development Kit)是Java开发工具包,提供了Java开发人员所需的开发工具和JRE。JRE(Java Runtime Environment)是Java运行环境,包括Java虚拟机(JVM)和Java程序所需的核心类库。JVM(Java Virtual Machine)是Java虚拟机,负责运行.class文件中的字节码指令。简而言之,JDK包含JRE和开发工具,JRE包含JVM和标准类库,而JVM是实现Java跨平台特性的核心机制。
4. class 和 public class 的区别
Section titled “4. class 和 public class 的区别”一个Java源文件可以定义多个类,编译后,每个类都会生成对应的.class字节码文件。如果一个类被声明为public,那么该类的名称必须与源文件名相同。一个源文件中可以没有public类,但如果有,那么只能有一个。每个类都可以包含一个main方法作为程序入口,但在实际开发中,通常只设定一个入口。
class A{ public static void main(String[] args) { System.out.println("A执行了"); }}class B{ public static void main(String[] args) { System.out.println("B执行了"); }}public class X{ public static void main(String[] args) { System.out.println("X执行了,这个 Java 源文件名为 X.java"); }}5. Java标识符命名规范
Section titled “5. Java标识符命名规范”Java 标识符的命名遵循驼峰命名法:
- 类名、接口名: 首字母大写,后续每个单词首字母大写。例如:
StudentService - 变量名、方法名: 首字母小写,后续每个单词首字母大写。例如:
productPrice - 常量名: 全部大写,单词之间使用下划线分隔。例如:
LOGIN_SUCCESS - 包名: 全部小写。例如:
com.camellia.javase.extends
6. Java中的加号运算符
Section titled “6. Java中的加号运算符”public class PlusTest{ public static void main(String[] args) { int a=10; int b=20; String str="10"; // 字符串拼接 System.out.println(str + b); // 1020; str="30"; // 当一个表达式中出现多个+,若没有(),遵循从左到右。 System.out.println(a + b + str); // 3030; // 添加了()优先级比较高。 System.out.println(a+(b+str)); // 102030 }}7. 变量的分类
Section titled “7. 变量的分类”- 局部变量(Local Variables): 在方法、代码块或构造方法中声明的变量称为局部变量。局部变量只在其声明的范围内可见,超出该范围就无法访问。局部变量的生命周期仅在其声明的代码块、方法或构造方法执行期间。当代码块或方法执行完毕时,局部变量将被销毁。
- 成员变量(Instance Variables): 在类中声明的变量,但在方法之外,类的任何地方都可以访问,称为成员变量或实例变量。每个对象都有一份成员变量的副本,它们属于对象的状态。成员变量的生命周期与对象的生命周期相同。它们随着对象的创建而创建,随着对象的销毁而销毁。
- 静态变量(Static Variables): 使用 static 关键字声明的成员变量称为静态变量。静态变量属于类而不是对象,在类加载时初始化,并且所有对象共享同一份静态变量。静态变量的生命周期与类的生命周期相同。它们在类加载时初始化,随着类的卸载而销毁。
public class VarClassify { public static void main(String[] args) { // 凡是在方法体中定义的变量,一定是局部变量。 // 局部变量只在当前方法体中有效。 int a=100; }
// 在类中定义的变量叫做成员变量。 // 实例变量 int b=200; // 静态变量 static int c=300;}8. 原码、反码、补码
Section titled “8. 原码、反码、补码”8.1. byte与bit
Section titled “8.1. byte与bit”字节(byte)是计算机数据存储和处理的基础单位,通常由8个比特(bit)构成。每个比特是计算机中最小的数据存储单位,它只能表示0或1这两种状态。因此,一个字节能够表示8个比特(bit)的信息。
在计算机中,数据通常以字节(byte)为单位进行存储和传输,而比特(bit)是表示数据的最小单位。
- 1
KB= 1024byte - 1
MB= 1024KB - 1
GB= 1024MB - 1
TB= 1024GB
8.2. 原码、反码、补码概念及其转换
Section titled “8.2. 原码、反码、补码概念及其转换”原码、反码和补码是计算机中表示整数的三种不同方法,它们在位运算和数值计算中扮演着关键角色。以下是它们的定义及其相互转换的方法:
8.2.1. 概念
Section titled “8.2.1. 概念”- 原码(源码):
- 原码是整数的最基本的二进制表示形式。
- 正数的原码与其二进制表示形式相同,即最高位为 0。
- 负数的原码最高位为 1,其余位为对应正数的二进制表示。
- 反码:
- 反码是基于原码生成的,其中正数的反码与其原码一致,而负数的反码则是将原码的符号位保持不变,其余各位进行取反操作后得到的。
- 例如,在8位二进制数中,正数的反码与原码相同,而负数的反码则是将符号位保持不变,其余各位进行取反。
- 补码:
- 补码的定义是基于反码,其中正数的补码与其原码一致,而负数的补码则是在其反码的基础上加1得到。
- 例如,在8位二进制数中,正数的补码与原码是相同的,而负数的补码则是其反码加1得到的。
8.2.2. 源码转补码
Section titled “8.2.2. 源码转补码”- 正数的原码、反码、补码都相同。
- 负数的反码是将原码除符号位外各位取反得到的。
- 负数的补码是将其反码加 1 得到的。
举例来说,假设有一个 8 位二进制补码表示的负数 -5,补码为 11111011。按照上述步骤转换为原码:
- 判断符号位:符号位为 1,表示是负数。
- 求反码:除符号位外的各位取反,得到 10000100(反码)。
- 求反码加 1:将反码加 1,得到 10000101(原码)。
8.2.3. 补码转源码
Section titled “8.2.3. 补码转源码”- 判断补码的符号位: 补码的最高位是符号位。如果符号位为 0,则表示补码表示的是正数;如果符号位为 1,则表示补码表示的是负数。
- 分情况讨论:
- 如果补码表示的是正数,则补码、原码和反码相同,直接将补码作为原码即可。
- 如果补码表示的是负数,则执行下面的步骤:
- 求补码的反码: 将补码除符号位外的各位取反,得到反码。
- 求反码加 1: 将反码加 1,得到原码。
其中值得注意的是-128,它的源码与补码相同。 其原码、反码、补码如下:
- 原码:10000000
- 反码:11111111
- 补码:10000000
所以一个byte(字节)的范围是-128~127,可以表示256种不同的情况(中间包含一个零)。
此外,计算机系统底层采用补码表示法。Java是一种结合了编译和解释阶段的混合型语言。