Java 标识符、关键字与命名规范
语法规则决定"能不能编译通过",命名规范决定"能不能长期维护"。
一、什么是标识符(Identifier)
标识符就是程序员在编写代码时,为变量、方法、类、接口、包、常量、参数、枚举、注解等程序元素所起的名字。
凡是需要"起名字"的地方,都叫标识符。例如:
public class HelloWorld { // HelloWorld 是类名(标识符)
public static void main(String[] args) { // main / args 是标识符
int studentCount = 10; // studentCount 是变量名(标识符)
String name = "Java"; // name 是变量名(标识符)
printMessage(name); // printMessage 是方法名(标识符)
}
static void printMessage(String msg) { ... }
}
重要区分:关键字(keyword)、保留字(reserved word)、字面量(literal)不能作为标识符使用,它们是 Java 语言自己占用的名字。详见下文规则 3。
二、定义标识符的规则(语法规则,必须遵守)
这些是编译器的硬性规定,违反会直接编译报错。共有 4 条核心规则:
规则 1:组成字符限制
标识符只能由以下字符组成:
| 允许 | 说明 | 示例 |
|---|---|---|
字母 A-Z / a-z |
26 个英文字母(大小写敏感) | name, Age |
数字 0-9 |
不能作为开头字符 | count2, user1 |
下划线 _ |
可作开头(JDK 9 后单独使用 _ 被禁止) |
_temp, max_value |
美元符号 $ |
合法但不推荐(编译器/框架常用) | $value |
| Unicode 字符 | Java 支持中文等 Unicode 字符 | 姓名, 学生 |
int 年龄 = 20; // ✅ 合法(Unicode 支持),但工程中不推荐
int $price = 100; // ✅ 合法,但不推荐
int _ = 10; // ❌ JDK 9 起,单独的下划线被正式保留,禁止作为标识符
int user-name = 1; // ❌ 连字符 - 非法
规则 2:不能以数字开头
int 1num = 10; // ❌ 编译报错:不能以数字开头
int num1 = 10; // ✅ 正确
int _1num = 10; // ✅ 正确(数字前有其他字符即可)
规则 3:不能使用关键字、保留字和字面量
Java 共有 50 个关键字(其中 2 个"保留但从未使用")、3 个字面量(常被误认为关键字),外加 Java 10+ 引入的一批上下文关键字。权威出处是 JLS(Java 语言规范)§3.9。
3.1 先分清几个概念
| 概念 | 定义 | 能否用作标识符 | 例子 |
|---|---|---|---|
| 标识符 | 程序员给类、方法、变量起的名字 | —— | Person、name、main |
| 关键字 | 语言预定义、已被语法"征用"的词 | ❌ 不能 | class、if、int |
| 保留字 | 为将来扩展预留、当前语法未启用的词 | ❌ 不能 | const、goto |
| 字面量 | 代码里直接写出的"值" | ❌ 不能 | 123、"abc"、true、null |
| 上下文关键字 | 只在特定语境中才有关键字含义的词 | ✅ 其他语境可以 | var、record、sealed |
"能否用作标识符"的意思是:这个词还能不能拿来给你的类、方法、变量起名字。
int age = 1; // ✅ age 是普通词,可以起名 int class = 1; // ❌ class 是关键字,已被语法占用 int const = 1; // ❌ const 是保留字,已被预定 int true = 1; // ❌ true 是字面量 String var = "x"; // ✅ var 是上下文关键字,这里可以(但不推荐)
关键字(Keyword)
- 语言预定义的、有固定语法含义的词,编译器直接按语法规则解释。
- 已被语法"征用",含义固定(
class声明类、if条件判断)。 - 不能用作标识符;全部小写;IDE 中通常高亮显示。
保留字(Reserved Word)
- 为将来语法扩展预留的词——当前没有任何语法含义,但禁止程序员使用。
- Java 只有 2 个:
const、goto,相当于关键字的"候选池"。
两者关系一句话概括:被语法启用的保留词,就是关键字。const / goto 进了"候选池"却从没上岗——它们名字列在 JLS 的 50 个关键字清单里(所以总数是 50),但语法中查无此词,属于"名存实亡"的成员。
字面量(Literal)
- 代码中直接写出的值本身,如
123、"abc"、true、null。 - 它不是语法结构词,但因为同样不能作标识符,常被误认成关键字。
上下文关键字(Contextual Keyword)
- Java 10+ 的折中设计——只在特定语法位置才被解释为关键字,其他位置仍可当普通标识符用,保证旧代码不被破坏。
3.2 50 个关键字(按用途分类)
| 分类 | 数量 | 关键字 |
|---|---|---|
| 访问控制 | 3 | private protected public |
| 声明与修饰符 | 14 | abstract class enum extends final implements interface native new static strictfp synchronized transient volatile |
| 程序控制 | 13 | assert break case continue default do else for if instanceof return switch while |
| 异常处理 | 5 | catch finally throw throws try |
| 包相关 | 2 | import package |
| 基本类型 | 8 | byte short int long float double char boolean |
| 引用与返回 | 3 | this super void |
| 保留字 | 2 | const goto |
3.3 3 个字面量(不是关键字!)
| 字面量 | 含义 | 示例 |
|---|---|---|
true |
boolean 类型的真值 | boolean ok = true; |
false |
boolean 类型的假值 | boolean ok = false; |
null |
引用类型的空值,表示"不指向任何对象" | String s = null; |
为什么容易被误认为关键字:它们不能用作标识符(int true = 1; 编译报错),行为和关键字一样;IDE 里同样有高亮显示;有些教材把它们算进关键字,得出"Java 有 53 个关键字"的说法——严格按 JLS,它们是字面量,和 123、"abc" 一样是"值"。
3.4 上下文关键字与受限关键字
Java 10+ 引入的上下文关键字(Contextual Keyword),只在特定语境中才有关键字含义,其余地方仍可当标识符用(为兼容旧代码):
| 关键字 | 引入版本 | 生效语境 |
|---|---|---|
var |
Java 10 | 局部变量类型推断(实际是"受限类型名" reserved type name) |
record |
Java 16 | 记录类声明 |
sealed |
Java 17 | 密封类/接口声明 |
permits |
Java 17 | sealed 的许可子类列表 |
non-sealed |
Java 17 | 解除密封 |
yield |
Java 14 | switch 表达式中返回值 |
注意:
var严格说是"受限类型名"(reserved type name),只用于局部变量类型推断,不能用于字段、方法参数、返回类型。
模块系统(Java 9)还有一批受限关键字,只在 module-info.java 里生效:
module requires exports opens to uses provides with open transitive
3.5 关键字/保留字示例
int class = 10; // ❌ class 是关键字
int goto = 20; // ❌ goto 是保留字
int Class = 10; // ✅ 合法(Class 大写,Java 大小写敏感)
int classRoom = 5; // ✅ 合法(整体不是关键字)
规则 4:大小写敏感,长度无限制
- Java 严格区分大小写:
Name和name是两个不同的标识符。 - 长度无理论上限(但工程上不要过长,见命名规范)。
int age = 18;
int Age = 20; // ✅ 与 age 是两个不同变量,合法但极易混淆,禁止这样写
小结记忆口诀:标识符 = 字母/下划线/美元符开头 + 数字/字母/下划线/美元符 + 非关键字/保留字/字面量。
三、容易踩的坑
const和goto是保留字——从 C++ 沿袭的语法槽位,Java 从未启用,也不允许你定义名为const的变量。var不是关键字(Java 10+)——它是"受限类型名"(reserved type name),只能用于局部变量类型推断。- 上下文关键字(Java 14–17+)——只在特定语境中才有关键字含义,其余地方仍可当标识符用(为了兼容旧代码)。
_下划线:Java 9 起单独的下划线被正式保留,不能作标识符——Oracle 为未来的语法特性占的坑。- 模块系统(Java 9)的受限关键字
modulerequiresexportsopenstousesprovideswithopentransitive——只在module-info.java里生效。 strictfp从 Java 17 起语义上已废弃(JEP 306:浮点运算默认严格),但关键字本身仍保留。
四、Java 名称命名规范(约定俗成,工程必遵守)
语法规则只保证"能编译",命名规范保证"能读懂、能协作"。规范不是编译器强制的,但违反会降低代码可读性、触发 Code Review 被退回、违反阿里/Google 等编码规约。
4.1 总体原则(阿里 Java 开发手册核心)
- 见名知意:名字必须表达实际含义,杜绝无意义命名。
- 规范统一:同一个项目、同一类元素使用统一风格。
- 全英文命名:禁止拼音、拼音+英文混用(如
shuJu)。 - 缩写谨慎:除公认缩写(
id、url、http、api、dao、vo)外,不随意缩写。
4.2 各类元素的命名规范(核心对照表)
| 元素类型 | 命名风格 | 示例 | 错误示例 |
|---|---|---|---|
| 包名 | 全小写,点分隔,一般用域名倒写 | com.alibaba.fastjson |
com.Alibaba |
| 类名 / 接口名 | 大驼峰 PascalCase(首字母大写) | UserService、HttpClient |
userService |
| 方法名 | 小驼峰 camelCase(动词/动词短语开头) | getUserName()、saveOrder() |
GetUserName |
| 变量名 | 小驼峰(名词) | userName、orderTotal |
UserName |
| 常量名 | 全大写 + 下划线分隔 | MAX_COUNT、DEFAULT_SIZE |
maxCount |
| 参数名 | 小驼峰(与变量一致) | userId、pageSize |
UserID |
| 枚举类名 | 大驼峰;枚举值全大写+下划线 | Color.RED、Status.PROCESSING |
Color.red |
| 泛型参数 | 单个大写字母 | <T>、<E>、<K,V> |
<Type> |
| 测试类 | 被测类名 + Test 后缀 |
UserServiceTest |
TestUserService |
4.3 驼峰命名法详解
// 大驼峰(PascalCase):每个单词首字母大写 —— 用于类名、接口名
public class OrderServiceImpl implements OrderService { }
// 小驼峰(camelCase):首单词小写,其余单词首字母大写 —— 用于方法、变量
private int orderTotalCount;
public String getUserName() { return null; }
// 全大写 + 下划线(UPPER_SNAKE_CASE)—— 用于常量
public static final int MAX_RETRY_TIMES = 3;
4.4 布尔类型变量命名(阿里规约强制)
布尔类型变量,不要加 is 前缀,否则部分框架序列化会出问题:
boolean success = true; // ✅ 正确
boolean isSuccess = true; // ❌ 错误,禁止 is 前缀
// 但 POJO 类中的布尔字段对应 getter 用 isXxx(框架规范)
private boolean deleted;
public boolean isDeleted() { return deleted; } // ✅ getter 允许 is
4.5 分层/场景命名约定(大厂常见)
| 场景 | 约定 | 示例 |
|---|---|---|
| Service 层接口 | XxxService |
UserService |
| Service 实现 | XxxServiceImpl |
UserServiceImpl |
| DAO/Mapper 层 | XxxDao / XxxMapper |
UserDao、UserMapper |
| 实体类 | XxxDO / XxxPO / XxxEntity |
UserDO、UserPO |
| 数据传输对象 | XxxDTO / XxxVO / XxxBO |
UserDTO、UserVO |
| 工具类 | XxxUtils / XxxUtil |
StringUtils、DateUtil |
| 常量类 | XxxConstants |
RedisKeyConstants |
| 异常类 | XxxException |
BusinessException |
| 配置类 | XxxConfig / XxxProperties |
RedisConfig |
4.6 命名反例与正例对照
// ❌ 反例
int a = 1; // 无意义
String s; // 无意义
int shuJu = 10; // 拼音
String user_name = "tom"; // 变量用了下划线风格(应为 camelCase)
class USER { } // 类名全大写
public static final int MaxCount = 3; // 常量未全大写
// ✅ 正例
int studentAge = 18;
String studentName;
int dataCount = 10;
String userName = "tom";
class User { }
public static final int MAX_COUNT = 3;
五、总结
1. 先有概念,再看清单:关键字 = 被语法启用的保留词;保留字 = 预留未启用的词(const、goto);字面量 = 值;上下文关键字 = 特定语境才生效。
2. 记住三层结构:50 关键字 + 3 字面量 + 上下文关键字。
- 50 个关键字分八大类:访问控制、声明与修饰符、程序控制、异常处理、包相关、基本类型、引用与返回、保留字。
- 2 个保留字(
const、goto)从未启用,仅占语法槽位。 - 3 个字面量(
true/false/null)不是关键字,但同样不能作标识符。 - 上下文关键字(
var、record、sealed、permits、non-sealed、yield)是 Java 10+ 的现代化设计。
3. 语法规则 vs 命名规范对比:
| 维度 | 语法规则(硬性) | 命名规范(软性) |
|---|---|---|
| 是否强制 | 编译器强制,违反报错 | 团队约定,违反不报错 |
| 关注点 | 能否编译通过 | 能否读懂、维护 |
| 约束来源 | Java 语言规范(JLS) | 阿里规约 / Google Style / 团队规范 |
| 典型条款 | 不能以数字开头、不能用关键字 | 驼峰命名、见名知意、不用拼音 |
一句话总结:语法规则决定下限,命名规范决定上限。 前者是 Java 的准入证,后者是成为一名合格工程师(尤其大厂工程师)的基本功。日常写代码不必死记——IDE 高亮会帮你内化,但分类表让你"按功能检索",坑点清单让你避开误区。

浙公网安备 33010602011771号