关键字与标识符
关键字(Keywords)
关键字是 Java 语言预先定义的、具有特殊含义的单词,用于表示语法结构或特定功能。关键字不能被用作标识符(如变量名、类名等)。特点:
- 全部为小写字母(部分保留字如 const、goto 也是小写)。
- 具有特定语法含义,编译器会对其进行特殊处理。
常用关键字分类:
- 数据类型相关:
int、double、float、boolean、char、byte、short、long、void、String(注意:String 是类名,不是关键字,但习惯上当作特殊类型使用)。
- 流程控制相关:
if、else、switch、case、default、for、while、do、break、continue、return。
- 类与对象相关:
class、interface、enum、extends、implements、new、this、super、instanceof。
- 访问修饰符:
public、private、protected、default(默认访问权限,无关键字,通过不写修饰符表示)。
- 其他常用:
static、final、abstract、volatile、synchronized、package、import、try、catch、finally、throw、throws。
- 保留字(目前未使用但未来可能会用):
const、goto。
标识符(Identifiers)
标识符是程序员在编写代码时自定义的名称,用于标识类、方法、变量、常量、包等。命名规则(必须遵守,否则编译报错):
- 由字母(A-Z、a-z)、数字(0-9)、下划线(_)、美元符号($)组成。
- 不能以数字开头。
- 不能使用 Java 关键字或保留字。
- 区分大小写(如 name 和 Name 是两个不同的标识符)。
- 没有长度限制,但建议简洁明了。
命名规范(约定俗成,提高可读性):
- 类名 / 接口名:采用帕斯卡命名法(PascalCase),首字母大写,如 HelloWorld、UserService。
- 方法名 / 变量名:采用驼峰命名法(camelCase),首字母小写,后续单词首字母大写,如 getUser()、studentAge。
- 常量名:全部大写,单词之间用下划线分隔,如 MAX_SIZE、PI。
- 包名:全部小写,通常以域名反转开头(避免重名),如 com.example.util。
示例(正确与错误对比):
// 正确的标识符
public class Student {
private String studentName; // 变量名(驼峰)
public static final int MAX_AGE = 100; // 常量名(全大写)
public void study() { // 方法名(驼峰)
int score = 90; // 局部变量名
}
}
// 错误的标识符(原因说明)
// int 123num; // 错误:以数字开头
// int my-name; // 错误:包含非法字符“-”
// int class; // 错误:使用关键字“class”
// int Name; // 与“name”是不同标识符,但命名不规范(变量名应小写开头)
数据类型
Java 中的数据类型分为两大类:基本数据类型(Primitive Types)和引用数据类型(Reference Types)。它们的存储方式和使用场景有显著区别。
基本数据类型(8 种)
基本数据类型直接存储数据值,而非地址,适用于存储简单的数值或布尔值。根据用途可分为四类:
整数类型(整数数值)
| 类型 | 占用空间 | 取值范围 | 说明 |
|---|---|---|---|
byte | 1 字节 | -128 ~ 127 | 最小整数类型 |
short | 2 字节 | -32768 ~ 32767 | 短整数 |
int | 4 字节 | -2^31 ~ 2^31-1(约 ±21 亿) | 最常用的整数类型 |
long | 8 字节 | -2^63 ~ 2^63-1 | 长整数,赋值时需加 L |
示例:
byte b = 100;
int num = 1000;
long bigNum = 10000000000L; // 必须加L(大小写均可,建议大写)
浮点类型(小数数值)
| 类型 | 占用空间 | 取值范围 | 说明 |
|---|---|---|---|
float | 4 字节 | 约 ±3.4×10^38(精度 6-7 位小数) | 单精度浮点,赋值需加 F |
double | 8 字节 | 约 ±1.8×10^308(精度 15-17 位小数) | 双精度浮点,默认浮点类型 |
示例:
float f = 3.14F; // 必须加F(大小写均可)
double d1 = 3.14; // 默认是double类型
double d2 = 1.2e3; // 科学计数法(1.2×10³ = 1200)
字符类型
| 类型 | 占用空间 | 取值范围 | 说明 |
|---|---|---|---|
char | 2字节 | 0~65535(Unicode字符) | 存储单个字符,用单引号 |
示例:
char c1 = 'A'; // 单个字符
char c2 = '中'; // 可存储中文(Unicode支持)
char c3 = '\u0061'; // Unicode编码(对应字符 'a')
布尔类型(逻辑值)
| 类型 | 占用空间 | 取值范围 | 说明 |
|---|---|---|---|
boolean | 不确定(通常 1 字节) | true(真)或 false(假) | 用于逻辑判断 |
引用数据类型
引用数据类型存储的是对象的内存地址(引用),而非数据本身。包括以下几类:
- 类(Class):如 String、自定义类(Student、Car 等)。
- 接口(Interface):如 List、Runnable 等(需通过实现类使用)。
- 数组(Array):无论存储基本类型还是引用类型,数组本身都是引用类型。
- 枚举(Enum)、注解(Annotation) 等特殊引用类型。
基本类型与引用类型的核心区别
| 特性 | 基本数据类型 | 引用数据类型 |
|---|---|---|
| 存储内容 | 直接存储数据值 | 存储对象的内存地址(引用) |
| 默认值 | 有默认值(如 int 默认 0) | 默认值为 null(未指向任何对象) |
| 内存分配位置 | 栈内存(局部变量) | 对象在堆内存,引用在栈内存 |
| 传递方式 | 值传递(复制数据) | 引用传递(复制地址) |
自动类型转换与强制类型转换
自动类型转换(隐式转换)
当两种类型兼容且目标类型范围更大时,自动转换:
int a = 100;
long b = a; // int → long(自动转换,范围扩大)
double c = 3.14f; // float → double(自动转换)
强制类型转换(显示转换)
当目标类型范围更小或不兼容时,需手动转换(可能丢失精度):long x = 1000;
int y = (int)x; // long → int(强制转换)
double m = 3.14;
int n = (int)m; // 结果为3(丢失小数部分)
变量与常量
变量(Variable)
变量是程序运行过程中值可以改变的存储空间,用于临时存储数据。
变量的定义
定义变量的语法:
数据类型 变量名; // 声明变量
示例:
int age; // 声明int类型变量age
String name; // 声明String类型变量name
double salary; // 声明double类型变量salary
变量的初始化
变量必须先初始化(赋值)才能使用,否则编译报错。初始化有两种方式:
- 声明时直接初始化:
int age = 20; // 声明并初始化int变量
String name = "Alice"; // 声明并初始化String变量
boolean isStudent = true; // 声明并初始化boolean变量
- 先声明后初始化:
int score;
score = 95; // 后续赋值(使用前必须完成)
变量的作用域(Scope)
变量的作用域是指变量可被访问的有效范围,超出范围后变量会被销毁。根据定义位置不同,分为:- 局部变量:在方法、代码块(如 if、for)中定义的变量。
- 作用域:从定义处开始,到所在代码块结束为止。
- 特点:必须手动初始化才能使用,无默认值。
public class VariableDemo {
public static void main(String[] args) {
int a = 10; // 局部变量,作用域在main方法内
if (a > 5) {
int b = 20; // 局部变量,作用域仅在if代码块内
System.out.println(a + b); // 正确:a和b均在作用域内
}
// System.out.println(b); // 错误:b已超出作用域
}
}
- 成员变量:在类中定义(方法外)的变量,也称为实例变量。
- 作用域:整个类内部(所有方法均可访问)
- 特点:有默认值(如
int默认 0,String默认null),无需手动初始化即可使用。
public class VariableDemo {
// 成员变量(有默认值:0)
int num;
public void printNum() {
System.out.println(num); // 正确:可直接使用(默认值0)
}
public static void main(String[] args) {
VariableDemo obj = new VariableDemo();
obj.printNum(); // 输出:0
}
}
- 静态变量:在类中用 static 修饰的变量,属于类本身。
- 作用域:整个类,甚至其他类(通过类名访问)。
- 特点:有默认值,生命周期与类一致。
public class VariableDemo {
// 静态变量
static String school = "Sunny School";
public static void main(String[] args) {
System.out.println(VariableDemo.school); // 直接通过类名访问
}
}
常量(Constant)
常量是程序运行过程中值不可改变的量,通常用于存储固定数据(如数学常数、配置参数)。常量的定义
Java 中通过 final 关键字定义常量,语法:
final 数据类型 常量名 = 值; // 必须初始化,且后续不可修改
命名规范:常量名通常全部大写,单词间用下划线分隔。
示例:
final double PI = 3.14159; // 数学常数
final int MAX_STUDENTS = 50; // 最大学生数
final String DEFAULT_NAME = "Guest"; // 默认名称
常量的特点
- 一旦赋值,不可再修改(否则编译报错):
final int LIMIT = 100;
// LIMIT = 200; // 错误:常量值不能修改
- 常量必须在声明时初始化(或在构造方法中初始化,针对成员常量):
public class ConstantDemo {
// 成员常量(可在构造方法中初始化)
final int VERSION;
public ConstantDemo(int v) {
VERSION = v; // 构造方法中初始化
}
}
常量的作用域
与变量类似,根据定义位置分为:- 局部常量:在方法或代码块中定义,作用域同局部变量。
- 成员常量:在类中定义(无
static),作用域同成员变量。 - 静态常量:在类中用
staticfinal修饰,作用域同静态变量(最常用,如Math.PI)。
变量与常量的核心区别
| 特性 | 变量(Variable) | 常量(Constant) |
|---|---|---|
| 关键字 | 无 | final |
| 值是否可变 | 可修改 | 不可修改(初始化后固定) |
| 初始化要求 | 局部变量必须手动初始化;成员变量有默认值 | 必须初始化(声明时或构造方法中) |
| 命名规范 | 驼峰命名法(如 studentAge) | 全大写 + 下划线(如 MAX_AGE) |
运算符
算术运算符
用于基本数学运算,包括:| 运算符 | 功能描述 | 示例 | 结果 |
|---|---|---|---|
+ | 加法运算 | 5 + 3 | 8 |
- | 减法运算 | 5 - 3 | 2 |
* | 乘法运算 | 5 * 3 | 15 |
/ | 除法运算(整数相除取整数部分) | 5 / 3 | 1 |
% | 取余(模运算) | 5 % 3 | 2 |
++ | 自增 | ++a(先加后用)、a++(先用后加) | |
-- | 自减 | 规则同自增 |
注意:
- 在
/和%运算中需要注意运算的类型。
数字在程序中可以分为两种,一种是整型,一种是浮点型,整型和整型的运算结果就是整型,不会出现浮点型。否则,就会出现浮点型。
int a = 10;
float c = 3.0f;
double d = 3.0;
System.out.println(a / c); // 3.3333333
System.out.println(a / d); // 3.3333333333333335
System.out.println(a % c); // 1.0
System.out.println(a % d); // 1.0
当浮点数除以 0 的时候,结果为 Infinity 或者 NaN。
System.out.println(10.0 / 0.0); // Infinity
System.out.println(0.0 / 0.0); // NaN
当整数除以 0 的时候(10 / 0),会抛出异常:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.itwanger.eleven.ArithmeticOperator.main(ArithmeticOperator.java:32)
- 前自增和后自增与前自减和后自减是有区别的
前自增:先增后用
后自增:先用后增
int x = 10;
int y = ++x;
System.out.println(y + " " + x);// 11 11
x = 10;
y = x++;
System.out.println(y + " " + x);// 10 11
自减同理。
赋值运算符
用于给变量赋值,包括**基础赋值**和**复合赋值**:| 运算符 | 功能描述 | 示例 | 等价表达式 |
|---|---|---|---|
= | 基础赋值 | a = 10 | - |
+= | 加后赋值 | a += 3 | a = a + 3 |
-= | 减后赋值 | a -= 3 | a = a - 3 |
*= | 乘后赋值 | a *= 3 | a = a * 3 |
/= | 除后赋值 | a /= 3 | a = a / 3 |
%= | 取余后赋值 | a %= 3 | a = a % 3 |
注意:
编译器会提示错误,因为 = 右侧的算术表达式默认为 int 类型,左侧是 short 类型的时候需要进行强转。
short a = 10;
short b = 10;
//a+=b;//a=a+b internally so fine
a = (short)(a + b);
System.out.println(a);
进行赋值运算时,需注意类型的边界问题,赋值后的结果不要超出类型边界:
int a = Integer.MAX_VALUE;
int b = 10000;
int c = a * b;
System.out.println(c); // -10000
比较运算符
用于比较两个值的关系,返回 boolean 类型(true/false):
| **运算符 ** | **功能描述 ** | 示例 | 结果 |
|---|---|---|---|
== | 判断是否相等 | 5 == 3 | false |
!= | 判断是否不相等 | 5 != 3 | true |
> | 判断左边是否大于右边 | 5 > 3 | true |
< | 判断左边是否小于右边 | 5 < 3 | false |
>= | 判断左边是否大于等于右边 | 5 >= 5 | true |
<= | 判断左边是否小于等于右边 | 5 <= 3 | false |
注意:
- 比较基本类型(如
int、double)时,==比较的是值; - 比较引用类型(如
String、对象)时,==比较的是内存地址(是否为同一个对象)。
逻辑运算符
用于连接布尔表达式,进行逻辑判断(返回 boolean 类型):
| 运算符 | 功能描述 | 示例 | 结果 |
|---|---|---|---|
&& | 两边都为 true 时结果为 true(短路特性:左边为 false 则右边不执行) | (5>3) && (2>1) | true |
| || | 两边有一个为 true 时结果为 true(短路特性:左边为 true 则右边不执行) | (5<3) || (2>1) | true |
! | 取反 | !(5>3) | false |
单逻辑与运算符(&):很少用,因为不管第一个条件为 true 还是 false,依然会检查第二个。
单逻辑或运算符(|):也会检查第二个条件。
短路特性演示:
int x = 1;
// 左边为false,右边的x++不执行,x仍为1
if (5 < 3 && x++ > 0) { ... }
位运算符
直接操作二进制位(适用于底层开发或性能优化):提示:(a=6 即 0110,b=3 即 0011)
| 运算符 | 功能描述(针对二进制位) | 示例 | 结果(二进制) | 结果(十进制) |
|---|---|---|---|---|
& | 按位与:对应位都为 1 则为 1 | a & b | 0010 | 2 |
| | | 按位或:对应位有一个为 1 则为 1 | a | b | 0111 | 7 |
^ | 按位异或:对应位不同则为 1 | a ^ b | 0101 | 5 |
~ | 按位取反:0 变 1,1 变 0 | ~a | 1001(补码) | -7 |
<< | 左移:整体左移 n 位,右边补 0(相当于乘 2ⁿ) | a << 1 | 1100 | 12 |
>> | 右移:整体右移 n 位,左边补符号位(相当于除 2ⁿ) | a >> 1 | 0011 | 3 |
>>> | 无符号右移:整体右移 n 位,左边补 0(忽略符号) | a >>> 1 | 0011 | 3 |
示例:
// 左移
System.out.println(10<<2);//10*2^2=10*4=40
System.out.println(10<<3);//10*2^3=10*8=80
System.out.println(20<<2);//20*2^2=20*4=80
System.out.println(15<<4);//15*2^4=15*16=240
// 右移
System.out.println(10>>2);//10/2^2=10/4=2
System.out.println(20>>2);//20/2^2=20/4=5
System.out.println(20>>3);//20/2^3=20/8=2
三目运算符(条件运算符)
Java 唯一的三元运算符,语法:条件表达式 ? 表达式1 : 表达式2;
- 若条件为 true,返回表达式 1 的值。
- 若条件为 false,返回表达式 2 的值。
int a=2;
int b=5;
int min=(a<b)?a:b;
System.out.println(min);
表达式与语句
在 Java 中,表达式(Expression)和语句(Statement)是构成程序的基本单元,二者既相关联又有明确区别:表达式(Expression)
表达式是由运算符、操作数(变量、常量、方法调用等) 组成的代码片段,能产生一个结果值。特点:
- 必须有返回值(结果可以是任意数据类型)。
- 可作为更大表达式的一部分,或嵌入到语句中。
常见类型:
- 简单表达式:
5 + 3 // 算术表达式,结果为8(int类型)
x > 10 // 比较表达式,结果为boolean类型
"Hello" + name // 字符串拼接表达式,结果为String类型
- 包含方法调用的表达式:
Math.max(a, b) // 调用方法,结果为a和b中的最大值
list.size() // 调用集合方法,结果为集合元素数量(int)
- 复合表达式:
(a + b) * (c - d) // 结果为两个子表达式的乘积
x > 5 && y < 10 // 逻辑表达式,结果为boolean类型
语句(Statement)
语句是执行特定操作的完整指令,通常以分号 ; 结尾(代码块语句除外),它不直接返回值,但会改变程序状态(如修改变量、控制流程等)。Java 中的语句可分为以下几类:
- 表达式语句(将表达式转换为语句)
在表达式后加 ; 即构成语句,主要用于执行有副作用的表达式(如赋值、自增、方法调用等):
x = 10; // 赋值表达式语句(修改变量x)
a++; // 自增表达式语句(修改变量a)
System.out.println(); // 方法调用表达式语句(执行打印操作)
注意:纯计算表达式(如 5 + 3;)作为语句无实际意义(计算结果未被使用),不建议这样写。
- 声明语句(变量 / 常量定义)
用于声明变量或常量的语句:
int age; // 声明变量语句
String name = "Alice"; // 声明并初始化变量语句
final double PI = 3.14; // 声明常量语句
- 控制流语句(改变程序执行顺序)
用于控制程序执行流程的语句,包括:
- 分支语句:
if-else、switch-case
if (score >= 60) {
System.out.println("及格");
} else {
System.out.println("不及格");
}
- 循环语句:
for、while、do-while
for (int i = 0; i < 5; i++) {
System.out.println(i);
}
- 跳转语句:
break、continue、return
while (true) {
if (condition) {
break; // 跳出循环
}
}
- 代码块语句(复合语句)
用 {} 包裹的一组语句,形成一个独立的执行单元,可用于限定作用域或组合多条语句:
// 代码块作为整体执行
{
int temp = 10;
System.out.println(temp);
}
// 代码块外无法访问temp(超出作用域)
代码块常与控制流语句结合使用(如 if、for 的 body 部分)。
表达式与语句的核心区别
| 特性 | 表达式(Expression) | 语句(Statement) |
|---|---|---|
| 核心功能 | 产生一个结果值 | 执行操作(改变程序状态) |
| 结尾符号 | 不需要分号(除非作为表达式语句) | 通常以分号 ; 结尾(代码块用{}) |
| 嵌入性 | 可嵌入到语句中(如作为 if 的条件) | 不能嵌入到表达式中 |
| 示例 | a + b、x > 5 | x = 10;、if (...) { ... } |
示例:表达式与语句的结合
// 表达式作为if语句的条件(表达式结果为boolean类型)
if (x + y > 100) { // x + y > 100 是表达式
int sum = x + y; // 声明语句 + 赋值表达式语句
System.out.println(sum); // 方法调用表达式语句
}
在这个例子中,x + y > 100 是表达式(产生 boolean 结果),而 if 块内的代码则由多条语句组成。