三、Java基础语法:标识符、关键字、数据类型、变量与常量、运算符与表达式、类型转换
Java基础语法是构建一切Java程序的基石。对于参加计算机二级考试的考生而言,掌握本章内容不仅是应对选择题的基础,更是后续理解面向对象编程、异常处理、集合框架等高级主题的前提。本章将系统讲解标识符与关键字的规范、数据类型的分类与内存占用、变量与常量的声明及生命周期、运算符的优先级与结合性,以及类型转换的规则与陷阱。我们将通过原理剖析、对比表格、代码案例和常见误区复盘,帮助您建立扎实的语法功底。
3.1 标识符与关键字
3.1.1 核心原理
标识符是Java中用于命名变量、方法、类、接口、包等程序元素的名字。合法的标识符必须遵循以下规则:
- 组成字符:只能由字母(A-Z、a-z)、数字(0-9)、下划线(_)和美元符号($)组成。
- 首字符限制:不能以数字开头。
- 大小写敏感:
age和Age是两个完全不同的标识符。 - 不能是关键字:如
class、public、static等均不可用作标识符。 - 无长度限制:但实际使用中应保持简洁且具有描述性。
关键字是Java语言预先定义好的、具有特殊含义的保留字。Java共有53个关键字(含2个保留字 goto 和 const),它们不能作为标识符使用。常见关键字按功能可分为:访问控制(public、private、protected)、类与接口(class、interface、extends、implements)、数据类型(int、double、boolean)、流程控制(if、else、for、while)等。
3.1.2 命名规范与判断方法
虽然Java语法只规定了标识符的合法性,但业界通行一套命名规范,在考试中也可能作为判断题出现:
| 程序元素 | 命名规范 | 示例 | 反例 |
|---|---|---|---|
| 类名 | 大驼峰命名(每个单词首字母大写) | StudentInfo | studentInfo |
| 方法名/变量名 | 小驼峰命名(首单词小写,后续单词首字母大写) | getStudentName()、studentAge | GetStudentName() |
| 常量名 | 全大写,单词间用下划线分隔 | MAX_VALUE | maxValue |
| 包名 | 全小写,域名倒写 | com.example.demo | Com.Example |
2abc 非法(数字开头),my-name 非法(含连字符),class 非法(关键字)。
3.1.3 案例拆解
以下代码展示了合法与非法标识符的对比:
public class IdentifierDemo {
public static void main(String[] args) {
int studentAge = 20; // 合法,小驼峰
double _salary = 5000.5; // 合法,下划线开头
String $name = "Tom"; // 合法,美元符号开头
// int 2ndPlace = 2; // 非法:数字开头
// int my-score = 10; // 非法:含连字符
// int class = 1; // 非法:关键字
System.out.println(studentAge + " " + _salary + " " + $name);
}
}
3.1.4 常见误区与总结
true、false、null 是关键字。实际上它们是字面量(literal),但同样不能用作标识符。误区2:忽略大小写敏感性,将
Student 和 student 视为同一标识符。误区3:使用中文或特殊符号命名(虽然Java支持Unicode字符,但强烈不建议)。
3.2 数据类型
3.2.1 核心原理
Java是强类型语言,所有变量必须先声明类型再使用。数据类型分为两大类:基本数据类型(Primitive Types)和引用数据类型(Reference Types)。基本类型存储值本身,引用类型存储对象的地址。
Java的8种基本数据类型及其内存占用和取值范围如下表所示:
| 类型 | 关键字 | 占用字节 | 默认值 | 取值范围 |
|---|---|---|---|---|
| 字节型 | byte | 1 | 0 | -128 ~ 127 |
| 短整型 | short | 2 | 0 | -32768 ~ 32767 |
| 整型 | int | 4 | 0 | -2^31 ~ 2^31-1 |
| 长整型 | long | 8 | 0L | -2^63 ~ 2^63-1 |
| 单精度浮点 | float | 4 | 0.0f | 约 ±3.4E38(7位有效数字) |
| 双精度浮点 | double | 8 | 0.0d | 约 ±1.8E308(15位有效数字) |
| 字符型 | char | 2 | '\u0000' | 0 ~ 65535(Unicode字符) |
| 布尔型 | boolean | 1(JVM决定) | false | true / false |
3.2.2 判断方法与使用场景
选择数据类型时,应遵循以下原则:
- 整数优先用 int:除非数值超出int范围才用long。
- 小数默认是 double:float类型需在数值后加
f或F后缀。 - char 用于单个字符:使用单引号包裹,如
'A'。 - boolean 用于逻辑判断:不能与整数类型互相转换。
3.2.3 案例拆解
public class DataTypeDemo {
public static void main(String[] args) {
byte b = 100; // 合法,100在byte范围内
short s = 30000; // 合法
int i = 2000000000; // 合法
long l = 9000000000L; // 必须加L后缀,否则编译错误
float f = 3.14f; // 必须加f后缀
double d = 3.14159265358979;
char c = '中'; // 支持Unicode字符
boolean flag = true;
// 错误示例:
// byte b2 = 200; // 编译错误:超出byte范围
// float f2 = 3.14; // 编译错误:double不能自动转为float
// int i2 = 10L; // 编译错误:long不能自动转为int
}
}
3.2.4 常见误区与总结
误区2:将float变量直接赋值为double字面量,导致精度损失或编译失败。
误区3:认为char可以存储多个字符,实际上char只能存储单个Unicode字符(2字节)。
3.3 变量与常量
3.3.1 核心原理
变量是程序运行过程中值可以改变的量,其本质是内存中的一块存储区域。变量必须经过声明、初始化后才能使用。Java中的变量按作用域可分为:局部变量(方法内定义)、成员变量(类内定义)、静态变量(static修饰)。
常量是值在程序运行期间不可改变的量,使用 final 关键字修饰。常量名通常全大写,单词间用下划线分隔。常量必须在声明时或构造器中完成初始化,且只能赋值一次。
3.3.2 变量声明与初始化流程
- 声明:指定变量类型和名称,如
int count; - 初始化:为变量赋予初始值,如
count = 0;或声明时直接初始化int count = 0; - 使用:在作用域内读取或修改变量值。
3.3.3 案例拆解
public class VariableConstantDemo {
// 成员变量(实例变量)
int instanceVar = 10;
// 静态变量(类变量)
static int staticVar = 20;
// 常量
final double PI = 3.14159;
static final int MAX_SIZE = 100;
public void testMethod() {
int localVar = 30; // 局部变量,必须初始化
System.out.println(localVar);
// PI = 3.14; // 编译错误:final变量不能重新赋值
}
public static void main(String[] args) {
VariableConstantDemo obj = new VariableConstantDemo();
System.out.println(obj.instanceVar); // 通过对象访问
System.out.println(staticVar); // 直接访问静态变量
System.out.println(MAX_SIZE); // 直接访问静态常量
}
}
3.3.4 常见误区与总结
3.4 运算符与表达式
3.4.1 核心原理
运算符用于对操作数执行特定运算。Java运算符按功能分为:算术运算符、关系运算符、逻辑运算符、赋值运算符、位运算符、条件运算符(三元运算符)等。表达式是由运算符和操作数组成的符合语法规则的式子,每个表达式都有确定的值和类型。
3.4.2 运算符优先级与结合性
| 优先级 | 运算符 | 结合性 |
|---|---|---|
| 1(最高) | 括号 ()、数组下标 []、成员访问 . | 从左到右 |
| 2 | 正负号 + -、自增自减 ++ --、逻辑非 !、按位取反 ~ | 从右到左 |
| 3 | 乘除取模 * / % | 从左到右 |
| 4 | 加减 + - | 从左到右 |
| 5 | 移位 << >> >>> | 从左到右 |
| 6 | 关系 < <= > >= instanceof | 从左到右 |
| 7 | 相等 == != | 从左到右 |
| 8 | 按位与 & | 从左到右 |
| 9 | 按位异或 ^ | 从左到右 |
| 10 | 按位或 | | 从左到右 |
| 11 | 逻辑与 && | 从左到右 |
| 12 | 逻辑或 || | 从左到右 |
| 13 | 三元条件 ? : | 从右到左 |
| 14(最低) | 赋值 = += -= *= /= %= | 从右到左 |
3.4.3 案例拆解
public class OperatorDemo {
public static void main(String[] args) {
int a = 10, b = 3;
System.out.println("a + b = " + (a + b)); // 13
System.out.println("a / b = " + (a / b)); // 3(整数除法)
System.out.println("a % b = " + (a % b)); // 1(取模)
// 自增自减
int x = 5;
int y = x++; // y=5, x=6(先赋值后自增)
int z = ++x; // z=7, x=7(先自增后赋值)
// 短路逻辑
boolean flag1 = (a > 5) && (b++ > 0); // b不会自增,因为左侧为true,右侧执行
boolean flag2 = (a < 5) && (b++ > 0); // b不会自增,因为左侧为false,短路
System.out.println("b = " + b); // b = 4(只自增了一次)
// 三元运算符
int max = (a > b) ? a : b;
System.out.println("max = " + max);
}
}
3.4.4 常见误区与总结
5/2=2 而非2.5。若需小数结果,应写成 5.0/2 或 (double)5/2。误区2:混淆
&& 与 &:&& 具有短路特性,左侧为false时右侧不执行;& 两侧都会执行。误区3:赋值运算符与相等运算符混淆,如将
if (a == b) 误写为 if (a = b)。
3.5 类型转换
3.5.1 核心原理
类型转换是将一种数据类型的值转换为另一种数据类型的过程。Java支持两种类型转换方式:自动类型转换(隐式转换)和强制类型转换(显式转换)。
自动类型转换发生在小范围类型向大范围类型转换时,系统自动完成,无需显式声明。转换方向为:byte → short → int → long → float → double,且 char 可以自动转为 int 及以上类型。
强制类型转换用于大范围类型向小范围类型转换,可能造成数据溢出或精度损失,需使用 (目标类型) 语法显式转换。
3.5.2 判断方法与操作流程
- 判断是否自动转换:若目标类型范围大于源类型,且两者兼容(数值类型之间),则可自动转换。
- 判断是否需要强制转换:若目标类型范围小于源类型,或需要将浮点转为整数,则必须强制转换。
- 执行强制转换:在变量前加
(目标类型),如int i = (int) 3.14;
3.5.3 案例拆解
public class TypeCastDemo {
public static void main(String[] args) {
// 自动类型转换
int i = 100;
long l = i; // int → long,自动转换
float f = l; // long → float,自动转换(可能损失精度)
double d = f; // float → double,自动转换
// char → int
char c = 'A';
int ascii = c; // ascii = 65
// 强制类型转换
double pi = 3.14159;
int intPi = (int) pi; // intPi = 3(截断小数部分)
long bigNum = 3000000000L;
int smallNum = (int) bigNum; // 数据溢出,结果不可预测
// 表达式中的类型提升
byte b1 = 10, b2 = 20;
// byte sum = b1 + b2; // 编译错误:b1+b2结果为int
int sum = b1 + b2; // 正确:byte运算自动提升为int
System.out.println("intPi = " + intPi);
System.out.println("smallNum = " + smallNum);
System.out.println("sum = " + sum);
}
}
3.5.4 常见误区与总结
误区2:将大范围整数强制转为小范围整数时,可能发生溢出,结果不可预测,应避免。
误区3:boolean类型不能与其他任何类型进行转换。
3.6 综合实战:温度转换器
下面通过一个完整的案例,将本章知识点串联起来。该程序实现摄氏温度与华氏温度的相互转换,涉及变量声明、常量定义、运算符使用、类型转换等核心语法。
public class TemperatureConverter {
// 常量:华氏温度与摄氏温度的转换系数
static final double SCALE = 9.0 / 5.0;
static final int OFFSET = 32;
public static void main(String[] args) {
// 摄氏转华氏
double celsius = 37.5;
double fahrenheit = celsius * SCALE + OFFSET;
System.out.println(celsius + "°C = " + fahrenheit + "°F");
// 华氏转摄氏(强制类型转换演示)
int fahrenheitInt = 100;
double celsiusResult = (fahrenheitInt - OFFSET) * 5.0 / 9.0;
System.out.println(fahrenheitInt + "°F = " + celsiusResult + "°C");
// 整数运算陷阱:如果使用整数除法
double wrongResult = (fahrenheitInt - OFFSET) * 5 / 9; // 结果为整数
System.out.println("错误计算(整数除法): " + wrongResult);
// 正确方式:使用浮点除法
double correctResult = (fahrenheitInt - OFFSET) * 5.0 / 9;
System.out.println("正确计算(浮点除法): " + correctResult);
// 类型转换:将结果转为整数(截断)
int rounded = (int) correctResult;
System.out.println("截断后的整数结果: " + rounded);
}
}
运行结果分析:
37.5°C = 99.5°F
100°F = 37.77777777777778°C
错误计算(整数除法): 37.0
正确计算(浮点除法): 37.77777777777778
截断后的整数结果: 37
该案例展示了:final 常量的使用、自动类型转换(int→double)、强制类型转换(double→int)、整数除法与浮点除法的区别,以及表达式中的类型提升规则。考生应特别注意 5/9 与 5.0/9 的差异,这是考试中常见的易错点。
3.7 本章知识结构总结
| 知识点 | 核心要点 | 考试常见题型 |
|---|---|---|
| 标识符 | 字母、数字、_、$组成;不能数字开头;不能是关键字 | 判断标识符合法性 |
| 关键字 | 53个保留字;true/false/null是字面量 | 区分关键字与标识符 |
| 数据类型 | 8种基本类型;引用类型;默认值 | 类型范围、默认值选择 |
| 变量与常量 | final修饰常量;局部变量需初始化 | 变量作用域、常量赋值 |
| 运算符 | 优先级表;短路逻辑;自增自减 | 表达式求值、优先级判断 |
| 类型转换 | 自动转换方向;强制转换风险 | 转换结果判断、溢出分析 |