📚 7月30日课程复习笔记:Java基础与底层原理详解
本次课程深入剖析了Java语言的核心特性与底层运行机制。从Java“一次编写,到处运行”的跨平台原理出发,详细讲解了JDK、JRE与JVM的组成与关系。随后,课程深入计算机底层,系统阐述了原码、反码、补码的转换与运算规则,以及不同数据类型(int, float, boolean, char)在内存中的存储细节与性能权衡。最后,详细梳理了变量作用域、运算符优先级及位运算的巧妙应用。
第一部分:Java语言核心特性与运行机制
1. Java的八大核心特性
- 简单性:剔除了C/C++中复杂的指针操作和手动内存管理,引入自动垃圾回收机制,使编程更安全可靠。
- 面向对象:采用面向对象的编程思想,通过类和对象组织代码,支持封装、继承和多态,提高了代码的复用性和扩展性。
- 分布式:支持网络编程,程序可以在多台机器上协同运行,适用于处理大规模数据计算。
- 健壮性:具备严格的语法检测和异常处理机制,能有效防止数组越界、空指针等常见错误。
- 体系结构中立:Java程序不直接依赖特定的CPU架构(如x86, ARM),而是运行在Java虚拟机(JVM)之上。
- 可移植性:编译后的
.class字节码文件可以在任何安装了JVM的操作系统(Windows, Linux, macOS)上运行,实现“一次编写,到处运行”。 - 解释型:Java源代码先被编译成字节码,再由JVM解释或即时编译(JIT)成机器码执行。
- 高性能:支持多线程,能够同时处理多个任务,提高程序执行效率。
2. JDK、JRE与JVM的关系
- JDK (Java Development Kit):Java开发工具包,是程序员的“工具箱”。它包含了JRE以及编译器(
javac)、调试器等开发工具,用于开发和编译Java程序。 - JRE (Java Runtime Environment):Java运行时环境,是运行Java程序的必要环境。它包含了JVM和核心类库。
- JVM (Java Virtual Machine):Java虚拟机,是实现Java跨平台的核心。它负责加载、验证并执行字节码,将字节码“翻译”成特定操作系统的机器指令。
- 包含关系:JDK 包含 JRE,JRE 包含 JVM。
3. 环境变量与执行流程
- 环境变量 (Path):配置环境变量的目的是为了让操作系统能在任意目录下找到并执行JDK的
bin目录下的命令(如java,javac)。系统会按照当前目录 -> 环境变量Path中配置的路径顺序进行查找。 - 执行流程:
.java源文件 -> (javac编译) ->.class字节码文件 -> (JVM加载、解释/编译) -> 操作系统调用 -> CPU执行。
第二部分:数据类型与底层存储原理
1. 进制转换与编码基础
- 进制表示:二进制(前缀
0b)、八进制(前缀0)、十进制、十六进制(前缀0x)。 - 转换方法:
- 任意进制转十进制:位权展开法,即每一位数字乘以基数的位次方,然后求和。
- 十进制转任意进制:除基取余法,即不断除以目标进制数并记录余数,直到商为0,最后将余数倒序排列。
2. 原码、反码、补码
计算机内部使用补码来表示和存储有符号整数,以统一加减法运算并解决“0”的歧义问题。
- 原码:最高位为符号位(0正1负),其余位表示数值的绝对值。
- 反码:正数的反码与原码相同;负数的反码是符号位不变,其余位按位取反。
- 补码:正数的补码与原码相同;负数的补码是其反码加1。
- 为何使用补码:
- 统一运算:计算机只有加法器,减法通过加上负数的补码来实现。
- 解决双零问题:原码和反码中存在
+0和-0两种表示,浪费编码空间且导致逻辑复杂。补码中0只有一种表示(全0),而原本表示-0的编码(如8位下的10000000)被用来表示-128,使得8位有符号整数的范围变为-128到127。
3. 整型数据 (byte, short, int, long)
- 存储大小:
byte(8位),short(16位),int(32位),long(64位)。 - 默认类型与转换:
- 整数默认类型为
int。声明long类型变量时,若数值超出int范围,需在数字后加L。 byte和short在参与运算时,会先被自动提升为int类型再进行计算。- 强制类型转换:从大范围类型向小范围类型转换(如
int转byte)需要强制转换,可能导致数据溢出或精度丢失(截取低位)。
- 整数默认类型为
4. 浮点型数据 (float, double)
- 存储标准:遵循IEEE 754标准,分为符号位、阶码(指数)和尾数(数值)三部分。
- 存储结构:
float(32位):1位符号 + 8位阶码 + 23位尾数。double(64位):1位符号 + 11位阶码 + 52位尾数。
- 精度与范围:
- 浮点数能表示的数值范围极大,但有效位数有限(
float约6-7位)。 - 精度分布不均:数值越接近0,表示越精确(刻度密集);数值越大,相邻两个可表示数值的间隔越大(刻度稀疏),精度急剧下降。
- 因此,
float和int虽然都是32位,但int能精确表示范围内的所有整数,而float在大数值时无法精确表示所有整数。
- 浮点数能表示的数值范围极大,但有效位数有限(
5. 布尔型数据 (boolean)
- 底层实现:虽然逻辑上只需要1位(0或1),但在JVM底层通常实现为
int类型(32位)。 - 设计权衡:这是为了优化CPU缓存性能。CPU与内存交互的基本单位是缓存行(通常64字节)。如果
boolean只占1位或1字节,一个缓存行会加载过多数据,增加多线程竞争和等待的概率。将其设计为32位,可以减少缓存行内的数据项数量,提高访问效率。
6. 字符型数据 (char)
- 存储原理:字符在计算机中存储的不是图形,而是其对应的数字编码(如ASCII, Unicode)。
- 编码与乱码:
char类型在Java中占2字节(16位),采用Unicode编码。乱码产生的根本原因是文件存储时使用的编码规则与读取时使用的编码规则不一致。 - 流操作:文件流、网络流等底层本质上都是对字节或字符数组的操作。
第三部分:变量、运算符与位运算
1. 变量与常量
- 变量声明:Java是强类型语言,声明变量必须指定类型(
类型 变量名;)。 - 变量分类:
- 全局变量(成员变量):定义在类中,有默认初始值(如
int为0,boolean为false)。 - 局部变量:定义在方法中,没有默认值,必须手动初始化后才能使用。
- 全局变量(成员变量):定义在类中,有默认初始值(如
- 常量:使用
final关键字修饰,值在初始化后不可更改。 - 命名规范:类名大驼峰,方法和变量名小驼峰,常量全大写加下划线。
2. 运算符
- 算术运算符:
+,-,*,/,%。注意整数除法会向下取整(如5/2结果为2)。 - 自增/自减:
++,--。- 前置(
++i):先自增,再参与运算。 - 后置(
i++):先参与运算,再自增。 - 陷阱:
i = i++的结果是i的原始值,因为后置++会先保存i的旧值用于赋值,然后再自增,最后赋值操作将旧值覆盖回去。
- 前置(
- 三元运算符:
条件 ? 值1 : 值2,是if-else的简写形式。
3. 位运算
所有位运算都在补码基础上进行。
- 与 (&):两位都为1,结果为1。
- 或 (|):两位有一个为1,结果为1。
- 非 (~):按位取反。
- 异或 (^):两位不同,结果为1;两位相同,结果为0。
- 应用:不使用临时变量交换两个数
- 原理:利用异或运算的可逆性(
a ^ b ^ b = a)。 - 步骤:
a = a ^ b(此时a存储了a和b的差异信息)b = a ^ b(相当于(a ^ b) ^ b,结果为原始a的值,赋给b)a = a ^ b(相当于(a ^ b) ^ a,结果为原始b的值,赋给a)
- 原理:利用异或运算的可逆性(

2672

被折叠的 条评论
为什么被折叠?



