Java 语法基础
JDK 的组成
- JVM(Java 虚拟机):一种能将编译后的 Java 字节码(.class 文件)加载、验证、解释或即时编译并执行的抽象计算机环境。
- JRE(Java 运行时环境):包含 JVM、核心类库和其他必需组件,用于在本地系统上运行 Java 应用程序的完整环境。
- JDK(Java 开发工具包):在 JRE 基础上额外提供 Java 编译器(javac)、调试器等开发工具,用于编写和调试 Java 程序的套件。
注释类型
单行注释(Single-line Comment)
以//
开头,直到行尾都被视为注释。1
2// 这是一个单行注释
int x = 10; // 也可以放在代码行末多行注释(Block Comment)
以/*
开始,以*/
结束,适合注释多行内容。1
2
3
4
5/*
* 这是一个多行注释
* 可以覆盖多行文字
*/
int y = 20;文档注释(Javadoc Comment)
以/**
开始,以*/
结束,通常用于生成 API 文档,可放在类、方法、字段等声明之前。1
2
3
4
5
6
7
8
9
10/**
* 计算两个整数的和。
*
* @param a 第一个加数
* @param b 第二个加数
* @return 返回 a 与 b 的和
*/
public int add(int a, int b) {
return a + b;
}
字面量
- 整数字面量(Integer Literals)
- 十进制:
123
,0
- 八进制(以
0
开头):075
(等于十进制 61) - 十六进制(以
0x
或0X
开头):0xFF
,0X1A3
- 二进制(Java 7+,以
0b
或0B
开头):0b1010
,0B1101
- 长整型后缀:在数字后加
L
或l
,如12345678901L
- 十进制:
- 浮点数字面量(Floating-Point Literals)
- 十进制形式:
3.14
,0.001
,2.
- 科学计数法:
1.23e3
(×10³),4.56E-2
(×10⁻²) - 单精度后缀:在数字后加
F
或f
,如3.14F
- 双精度默认:如
2.71828
(等同于2.71828D
)
- 十进制形式:
- 字符字面量(Character Literals)
- 单引号括起的单个字符:
'a'
,'中'
,'$'
- 支持转义序列:
\n
,'\u4E2D'
,'\''
- 单引号括起的单个字符:
- 字符串字面量(String Literals)
- 双引号括起的字符序列:
"Hello, Java!"
,"换行:\n下一行"
- 支持所有字符转义:
\t
,\"
,\\
等
- 双引号括起的字符序列:
- 布尔字面量(Boolean Literals)
- 只有两个取值:
true
和false
- 只有两个取值:
- 空字面量(Null Literal)
- 用于表示引用类型不指向任何对象:
null
- 用于表示引用类型不指向任何对象:
变量声明
1 | [修饰符列表] 数据类型 变量名 [= 初始值] [, 变量名 [= 初始值] …] ; |
变量修饰符
package-private(默认)
不加任何访问修饰符时,称为包级私有。变量只对同一包内的类可见,包外不可访问。public
公开访问权限,声明为public
的变量对所有类可见,无论是否在同一包中。protected
受保护访问权限,声明为protected
的变量对同一包内的类及所有子类可见(即使子类在不同包中)。private
私有访问权限,声明为private
的变量仅在当前类内部可见,外部类和子类均无法直接访问。static
静态变量属于类本身而非某个实例。所有对象共享同一份static
变量,且可以通过ClassName.var
直接访问。final
常量修饰符,声明后必须在定义处或构造器中赋值,且赋值一次后不可再修改,常用于定义不可变值。transient
瞬态修饰符,指示该变量在对象序列化(Serializable
)时不被持久化写入序列化流。volatile
易变修饰符,保证多个线程访问该变量时的可见性和有序性:对一个线程写入的值,其他线程能立即看到,不会被线程本地缓存长期“隐藏”。
存储区域
- 局部变量 → 线程栈;实例变量 → 堆;静态变量 → 方法区。
基本类型 vs 引用类型
- 基本类型存值;引用类型存地址,实际对象在堆上。
变量访问
- 字节码通过
load
/store
(局部变量)和get
/put
(实例/静态变量)在操作数栈与内存区间搬运数据。
并发可见性
- 每线程独立栈;堆与方法区共享;
volatile
和synchronized
保证跨线程可见性与有序性。
生命周期
- 栈上随方法调用进出;静态随类加载/卸载;堆上随对象引用消失由 GC 回收。
自动类型转换
- 数值类型“向上”转换:编译器自动将容量小的类型提升到容量大的类型,顺序为
byte → short → int → long → float → double
,并且在算术运算中,byte
/short
/char
会先提升为int
。 char
到整数:char
可自动转为int
及更大类型。- 引用类型“向上”转型:子类对象可赋给父类引用,无需显式转换。
- 限制:只能“扩宽”或“子 → 父”,反之(“窄化”或“父 → 子”)必须显式强制转换。
强制类型转换
基本类型转换
窄化转换(大 → 小):需
(目标类型) 值
,可能截断或溢出。1
2int i = (int) 3.9; // i = 3
byte b = (byte) 130; // b = -126拓宽转换(小 → 大):自动完成,无需显式。
引用类型转换
上转型(子 → 父):隐式安全。
1
Animal a = new Dog();
下转型(父 → 子):需
(子类) 父引用
,若类型不符抛ClassCastException
。1
2
3if (a instanceof Dog) {
Dog d = (Dog) a;
}
常见注意点
- 混合运算:整型运算默升为
int
,赋小类型需显式转。 - 精度控制:如
(double) a / b
保留小数。 - 泛型前代码:对
Object
集合取出时需要转换,推荐使用泛型避免。
- 混合运算:整型运算默升为
要点:大 → 小要显式转换并谨防数据丢失;父 → 子要确认类型再转。
运算符
算术运算符
+
、-
、*
、/
、%
- 自增/自减:
++a
、a++
、--a
、a--
赋值运算符
- 简单赋值:
=
- 复合赋值:
+=
、-=
、*=
、/=
、%=
、&=
、|=
、^=
、<<=
、>>=
、>>>=
- 简单赋值:
关系(比较)运算符
==
、!=
>
、<
、>=
、<=
逻辑运算符
- 与:
&&
(短路),&
(非短路) - 或:
||
(短路),|
(非短路) - 非:
!
- 与:
位运算符
- 与:
&
- 或:
|
- 异或:
^
- 取反:
~
- 与:
位移运算符
- 左移:
<<
- 右移(带符号):
>>
- 右移(无符号):
>>>
- 左移:
三元运算符
condition ? expr1 : expr2
1
int max = (a > b) ? a : b;
其他运算符
- 类型检查:
instanceof
- 数组下标:
[]
- 方法调用:
()
- 成员访问:
.
、->
(仅用于 JNI) - 强制类型转换:
(Type) value
- 类型检查:
提示:运算符优先级影响表达式计算顺序,可参考官方文档或使用括号
()
来明确运算顺序。
程序流程控制
顺序执行
按代码书写顺序从上到下依次执行。分支(选择)
if
/if–else
/if–else if–else
1
2
3if (cond) { … }
else if (cond2) { … }
else { … }switch
1
2
3
4
5switch (expr) {
case 常量1: …; break;
case 常量2: …; break;
default: …;
}
循环(迭代)
for
循环1
2
3for (初始化; 条件; 更新) {
…
}**增强型
for
**(遍历数组/集合)1
2
3for (Type item : collection) {
…
}while
循环1
2
3while (条件) {
…
}do–while
循环1
2
3do {
…
} while (条件);
跳转控制
break
:退出最近的switch
或循环continue
:跳过本次循环、进入下一次迭代return
:结束方法并可返回值
异常处理
捕获/处理:
try–catch–finally
1
2
3
4
5
6
7try {
…
} catch (ExceptionType e) {
…
} finally {
…
}抛出异常:
throw new ExceptionType("msg");
要点:
- 用分支 (
if
/switch
) 做条件判断,- 用各种
for
/while
循环重复执行,- 配合
break
/continue
控制循环流程,- 用异常 (
try–catch
) 管理错误场景。
数组
1. 数组的定义
一维数组
1
2
3
4
5
6// 声明
int[] arr1;
String arr2[];
// 分配空间并初始化
arr1 = new int[5];
String[] arr3 = new String[] { "A", "B", "C" };多维数组
1
2
3
4
5
6// 二维数组
int[][] matrix = new int[3][4];
// 不规则二维数组
int[][] ragged = new int[3][];
ragged[0] = new int[2];
ragged[1] = new int[5];
2. 数组的遍历
传统
for
循环1
2
3for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}增强型
for
(foreach)1
2
3for (String s : arr) {
System.out.println(s);
}while
/do–while
1
2
3
4int i = 0;
while (i < arr.length) {
System.out.println(arr[i++]);
}
3. 存储原理
连续内存
数组在内存中占用一段连续空间,每个元素大小相同(基于元素类型)。索引访问
通过索引直接计算元素地址:1
元素地址 = 数组基地址 + 索引 * 元素字节长度
定长特性
数组长度在创建时确定,无法动态扩容;要变更长度需新建数组并复制元素。多维数组
Java 多维数组本质是“数组的数组”,最外层引用指向若干子数组,它们可分别分配内存(支持不规则矩阵)。
要点:
- 定义:用
new Type[size]
创建定长、同类型的存储结构;- 遍历:常用
for
/ 增强for
;- 存储:连续内存+索引直接定位,访问高效但尺寸固定。
方法
定义
1
2
3
4// 语法:[修饰符] 返回类型 方法名(参数列表) { 方法体 }
public int add(int x, int y) {
return x + y;
}执行原理
- 调用时在栈上为方法创建栈帧(包含局部变量、操作数栈等)。
- 执行方法体指令,使用操作数栈进行计算。
- 遇
return
弹出栈帧,将返回值(若有)传给调用者。
参数传递
- 基本类型:按值传递,方法内修改不影响外部变量。
- 引用类型:传递的是引用的副本(引用按值传)。方法内可通过该引用修改对象内容,但无法让引用指向新对象影响外部。
重载(Overload)
- 同一类中多个同名方法,参数列表(类型、个数、顺序)必须不同。
- 编译期根据调用时的静态类型和实际参数匹配最优方法签名。
- 与返回类型、抛出异常无关。