文章目录
- Java关键字及保留字总结(按首字母字母顺序所排列)
- 1.abstract
- 2.boolean
- 3.break
- 4.byte
- 5.case
- 6.catch
- 7.char
- 8.class
- 9.continue
- 10.default
- 11.do
- 12.double
- 13.else
- 14.enum
- 15.extends
- 16.final
- 17.finally
- 18.float
- 19.for
- 20.if
- 21.implements
- 22.import
- 23.instanceof
- 24.int
- 25.interface
- 26.long
- 27.native
- 28.new
- 29.null
- 30.package
- 31.private
- 32.protected
- 33.public
- 34.return
- 35.short
- 36.static
- 37.strictfp
- 38.super
- 39.switch
- 40.synchronized
- 41.this
- 42.throw
- 43.throws
- 44.transient
- 45.try
- 46.void
- 47.volatile
- 48.while
- 49.goto(保留字)
- 50.const(保留字)
Java关键字及保留字总结(按首字母字母顺序所排列)
本文来源二哥的Java进阶之路-5000字速通Java的48个关键字及2个保留字,这本教材我个人是十分喜欢的,抛弃了一些旧的技术,大大的节省了我们的时间成本。有学习Java的伙伴,可以看看这本书,真的不错,强推👍。
1.abstract
用于声明抽象类以及抽象方法。
abstract class Animal {
abstract void makeSound();
public void sleep() {
System.out.println("The animal is sleeping.");
}
}
class Dog extends Animal {
void makeSound() {
System.out.println("The dog barks.");
}
}
在这个示例中,我们创建了一个名为 Animal 的抽象类,其中包含一个抽象方法 makeSound()
和一个具体方法 sleep()
。
2.boolean
Java 中的一种基本数据类型,表示布尔值,即真(true)或假(false)。boolean 数据类型常用于判断条件、循环控制和逻辑运算等场景。
boolean isStudent = true;
if (isStudent) {
System.out.println("This person is a student.");
} else {
System.out.println("This person is not a student.");
}
在这个示例中,我们定义了一个 boolean 变量:isStudent。通过 if 语句,我们可以根据这些变量的值进行不同的操作。
3.break
用于跳出循环结构(如 for、while 和 do-while 循环)或 switch 语句。当遇到 break 语句时,程序将立即跳出当前循环或 switch 语句,继续执行紧跟在循环或 switch 语句后面的代码。
for (int i = 0; i < 10; i++) {
if (i == 5) {
break;
}
System.out.println("i: " + i);
}
System.out.println("Loop ended.");
在这个示例中,我们使用 for 循环遍历 0 到 9 的整数。当 i 等于 5 时,我们使用 break 语句跳出循环。
4.byte
用于表示一个 8 位(1 字节)有符号整数。它的值范围是 -128(-2^7)到 127(2^7 - 1)。
由于 byte 类型占用的空间较小,它通常用于处理大量的数据,如文件读写、网络传输等场景,以节省内存空间。
byte minByte = -128;
byte maxByte = 127;
在这个示例中,我们声明了两个 byte 类型的变量:minByte、maxByte,并分别赋予了不同的值。
5.case
通常与 switch 语句一起使用。switch 语句允许根据某个变量的值来选择执行不同的代码块。在 switch 语句中,case 用于标识每个可能的值和对应的代码块。
例子我们直接放到 switch 中一起讲。
6.catch
用于捕获 try 语句中的异常。在 try 块中可能会抛出异常,而在 catch 块中可以捕获这些异常并进行处理。catch 块可以有多个,每个 catch 块可以捕获特定类型的异常。在 catch 块中,可以根据需要进行异常处理,例如输出错误信息、进行日志记录、恢复程序状态等。
try {
int num = Integer.parseInt("abc");
} catch (NumberFormatException e) {
System.out.println("Invalid number format");
}
这个程序使用 try-catch 语句捕获 NumberFormatException 异常。在 try 块中,尝试将字符串 “abc” 转换为整数类型,由于这个字符串不是有效的数字格式,将会抛出 NumberFormatException 异常。在 catch 块中,捕获到了这个异常,并输出一条错误信息。
7.char
用于声明一个字符类型的变量。char 类型的变量可以存储任意的Unicode 字符,可以使用单引号将字符括起来来表示。
char c = 'A';
这个程序创建了一个 char 类型的变量 c,并将其赋值为大写字母 A。
8.class
用于声明一个类。
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void sayHello() {
System.out.println("Hello, my name is " + name + " and I am " + age + " years old.");
}
}
9.continue
用于继续下一个循环,可以在指定条件下跳过其余代码。
for (int i = 1; i <= 10; i++) {
if (i % 2 == 0) {
continue;
}
System.out.println(i);
}
10.default
用于指定 switch 语句中除去 case 条件之外的默认代码块。这个我们放到 switch 里一起演示。
11.do
通常和 while 关键字配合使用,do 后紧跟循环体。
int i = 1;
do {
System.out.println(i);
i++;
} while (i <= 10);
do-while 循环与 while 循环类似,不同之处在于 do-while 循环会先执行循环体中的代码,然后再检查循环条件。因此,do-while 循环至少会执行一次循环体中的代码。
12.double
用于声明一个双精度浮点类型的变量。
double a = 3.14;
double b = 2.0;
double c = a + b;
13.else
用于指示 if 语句中的备用分支。
int score = 75;
if (score >= 60) {
System.out.println("及格了");
} else {
System.out.println("挂科了");
}
14.enum
用于定义一组固定的常量(枚举)。
public enum PlayerType {
TENNIS,
FOOTBALL,
BASKETBALL
}
15.extends
用于指示一个类是从另一个类或接口继承的。
class Animal {
public void eat() {
System.out.println("动物正在吃东西");
}
}
class Dog extends Animal {
public void bark() {
System.out.println("狗在汪汪叫");
}
}
public class ExtendsDemo {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat();
dog.bark();
}
}
Animal 类中有一个 eat()
方法,输出字符串 “动物正在吃东西”。Dog 类继承自 Animal 类,并定义了一个 bark()
方法,输出字符串 “狗在汪汪叫”。
16.final
用于表示某个变量、方法或类是最终的,不能被修改或继承。
- final 变量:表示一个常量,一旦被赋值,其值就不能再被修改。这在声明不可变的值时非常有用。
final double PI = 3.14159265359;
- final 方法表示一个不能被子类重写的方法。这在设计类时,确保某个方法的实现不会被子类修改时非常有用。
class Animal {
final void makeSound() {
System.out.println("动物发出声音.");
}
}
class Dog extends Animal {
// 错误: 无法覆盖来自 Animal 的 final 方法
// void makeSound() {
// System.out.println("狗吠叫.");
// }
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.makeSound();
}
}
- final 类表示一个不能被继承的类。这在设计类时,确保其不会被其他类继承时非常有用。(String类就是final类型)
final class Animal {
void makeSound() {
System.out.println("动物发出声音.");
}
}
// 错误: 类型 Dog 无法继承 final 类 Animal
// class Dog extends Animal {
// void makeSound() {
// System.out.println("狗吠叫.");
// }
// }
public class Main {
public static void main(String[] args) {
Animal animal = new Animal();
animal.makeSound();
}
}
17.finally
和 try-catch
配合使用,表示无论是否处理异常,总是执行 finally 块中的代码。
try {
int x = 10 / 0; // 抛出异常
} catch (Exception e) {
System.out.println("发生了异常:" + e.getMessage());
} finally {
System.out.println("finally 块被执行");
}
18.float
表示单精度浮点数。
float f1 = 3.14f; // 注意要在数字后面加上 f 表示这是一个 float 类型
float f2 = 1.23e-4f; // 科学计数法表示小数
在 Java 中,浮点数默认是 double 类型,如果要使用 float 类型的数据,需要在数字后面加上一个 f 或者 F,表示这是一个 float 类型的字面量。另外,也可以使用科学计数法表示浮点数,例如 1.23e-4 表示 0.000123。
19.for
用于声明一个 for 循环,如果循环次数是固定的,建议使用 for 循环。
int[] arr = {1, 2, 3, 4, 5};
for (int i = 0; i < arr.length; i++) {
System.out.println("arr[" + i + "] = " + arr[i]);
}
20.if
用于指定条件,如果条件为真,则执行对应代码。
int n = -3;
if (n > 0) {
System.out.println(n + " 是正数");
} else if (n < 0) {
System.out.println(n + " 是负数");
} else {
System.out.println(n + " 是零");
}
21.implements
用于实现接口。下面是一个实现了 Runnable 接口的类的示例:
public class MyThread implements Runnable {
public void run() {
// 线程执行的代码
}
}
22.import
用于导入对应的类或者接口。例如,如果要使用 Java 标准库中的 ArrayList 类,可以这样写:
import java.util.ArrayList;
23.instanceof
用于判断对象是否属于某个类型(class)。
//例如,假设有一个 Person 类和一个 Student 类,Student 类继承自 Person 类,可以使用 instanceof 运算符来判断一个对象是否为 Person 类或其子类的实例:
Person p = new Student();
if (p instanceof Person) {
System.out.println("p is an instance of Person");
}
if (p instanceof Student) {
System.out.println("p is an instance of Student");
}
24.int
用于表示整数值。
int x; // 声明一个 int 类型的变量 x
x = 10; // 将整数值 10 赋给变量 x
int y = 20; // 声明并初始化一个 int 类型的变量 y,赋值为整数值 20
25.interface
用于声明接口。会定义一组方法的签名(即方法名、参数列表和返回值类型),但没有方法体。其他类可以实现接口,并提供方法的具体实现。
public interface MyInterface {
void method1();
int method2(String param);
}
26.long
用于表示长整数值。
long x; // 声明一个 long 类型的变量 x
x = 10000000000L; // 将长整数值 10000000000 赋给变量 x,需要在数字后面加上 L 或 l 表示这是一个 long 类型的值
long y = 20000000000L; // 声明并初始化一个 long 类型的变量 y,赋值为长整数值 20000000000
27.native
用于声明一个本地方法。本地方法是指在 Java 代码中声明但在本地代码(通常是 C 或 C++ 代码)中实现的方法,它通常用于与操作系统或其他本地库进行交互。
public native void nativeMethod();
28.new
用于创建一个新的对象。
以下是使用 new 关键字创建对象实例的基本语法:
ClassName obj = new ClassName();
以下是使用 new 关键字创建数组实例的基本语法:
int[] arr = new int[10];
29.null
如果一个变量是空的(什么引用也没有指向),就可以将它赋值为 null,和空指针异常息息相关。
String str = null; // 声明一个字符串引用,初始化为 null
MyClass obj = null; // 声明一个 MyClass 类型的引用,初始化为 null
30.package
用于声明类所在的包。
package com.example.mypackage;
31.private
一个访问权限修饰符,表示方法或变量只对当前类可见。
public class MyClass {
private int x; // 私有属性 x,只能在当前类的内部访问
private void foo() {
// 私有方法 foo,只能在当前类的内部调用
}
}
在这个示例中,MyClass 类有一个私有属性 x 和一个私有方法 foo()
。这些成员只能在 MyClass 类的内部访问和调用,对其他类不可见。
32.protected
一个访问权限修饰符,表示方法或变量对同一包内的类和所有子类可见。
package com.example.mypackage;
public class MyBaseClass {
protected int x; // 受保护的属性 x,可以被子类和同一包中的其他类访问
protected void foo() {
// 受保护的方法 foo,可以被子类和同一包中的其他类调用
}
}
package com.example.mypackage;
public class MySubClass extends MyBaseClass {
public void bar() {
x = 10; // 可以访问 MyBaseClass 中的受保护属性 x
foo(); // 可以调用 MyBaseClass 中的受保护方法 foo
}
}
在这个示例中,MyBaseClass 类有一个受保护的属性 x 和一个受保护的方法 foo()
。这些成员可以被子类和同一包中的其他类访问和调用。MySubClass 类继承自 MyBaseClass 类,并可以访问和修改 MyBaseClass 中的受保护成员。
33.public
一个访问权限修饰符,除了可以声明方法和变量(所有类可见),还可以声明类。main()
方法必须声明为 public。
public class MyClass {
public int x; // 公有属性 x,可以被任何类访问
public void foo() {
// 公有方法 foo,可以被任何类调用
}
}
在这个示例中,MyClass 类有一个公有属性 x 和一个公有方法 foo()
。这些成员可以被任何类访问和调用,无论这些类是否在同一个包中。
34.return
用于从方法中返回一个值或终止方法的执行。return 语句可以将方法的计算结果返回给调用者,或者在方法执行到某个特定条件时提前结束方法。
public int add(int a, int b) {
int sum = a + b;
return sum; // 返回 sum 的值,并结束方法的执行
}
此外,return 语句还可以用于提前结束方法的执行。例如,假设我们要编写一个方法,用于判断一个整数是否为偶数:
public static boolean isEven(int number) {
if (number % 2 == 0) {
return true;
}
return false;
}
在这个示例中,我们定义了一个名为 isEven 的方法,该方法接收一个整数参数 number。如果 number 是偶数,我们使用 return 语句提前返回 true。否则,方法执行将继续,最后返回 false。
35.short
用于表示短整数,占用 2 个字节(16 位)的内存空间。
short x = 10; // 声明一个 short 类型的变量 x,赋值为 10
short y = 20; // 声明一个 short 类型的变量 y,赋值为 20
36.static
表示该变量或方法是静态变量或静态方法。
public class MyClass {
public static int x; // 静态变量 x,属于类的成员
public static void foo() {
// 静态方法 foo,属于类的成员
}
}
在这个示例中,MyClass 类有一个静态变量 x 和一个静态方法 foo()
。这些成员属于类的成员,可以通过类名直接访问,不需要创建对象。
37.strictfp
strict floating-point,并不常见,通常用于修饰一个方法,用于限制浮点数计算的精度和舍入行为。当你在类、接口或方法上使用 strictfp 时,该范围内的所有浮点数计算将遵循 IEEE 754 标准的规定,以确保跨平台的浮点数计算的一致性。
不同的硬件平台和 JVM 实现可能对浮点数计算的精度和舍入行为有差异,这可能导致在不同环境中运行相同的浮点数计算代码产生不同的结果。使用 strictfp 关键字可以确保在所有平台上获得相同的浮点数计算结果,避免计算结果的不一致问题。
但请注意,使用 strictfp 可能会对性能产生影响,因为可能需要更多的计算和转换来确保遵循 IEEE 754 标准。因此,在使用 strictfp 时,需要权衡精度和一致性与性能之间的关系。
public strictfp class MyClass {
public static void main(String[] args) {
double a = 0.1;
double b = 0.2;
double result = a + b;
System.out.println("Result: " + result);
}
}
>>>Result: 0.30000000000000004
在这个示例中,MyClass 类被声明为 strictfp,因此类中的所有浮点数计算都将遵循 IEEE 754 标准。
在大多数现代操作系统上,使用 strictfp 可能不会产生显著差异,因为大家都遵循 IEEE 754 标准,除非是一些较旧的硬件平台。
IEEE 754 标准(IEEE Standard for Floating-Point Arithmetic)是一个定义浮点数表示和运算的国际标准。由国际电气和电子工程师协会(IEEE)制定,首次发布于1985年。
IEEE 754 标准主要规定了以下几个方面:
浮点数表示:标准定义了两种浮点数格式,单精度(32位)和双精度(64位)。这两种格式分别由符号位、指数位和尾数位组成,用于表示浮点数的大小和精度。
四舍五入和舍入模式:标准定义了多种舍入模式,例如向最接近的数舍入(Round to Nearest, Ties to Even)、向零舍入(Round toward Zero)、向正无穷舍入(Round toward +∞)和向负无穷舍入(Round toward -∞)等。这些模式指导了浮点数计算过程中如何处理精度损失和舍入误差。
特殊值:标准定义了一些特殊的浮点数值,如正无穷(+∞)、负无穷(-∞)和非数值(NaN)。这些特殊值用于表示浮点数计算中可能出现的溢出、下溢和未定义结果等情况。
浮点数运算:标准规定了浮点数的基本运算(加、减、乘、除)和比较运算(等于、不等于、大于、小于、大于等于、小于等于)的行为和结果。这些运算需要遵循标准中规定的表示、舍入和特殊值处理规则。
public class Ieee754Demo {
public static void main(String[] args) {
float a = 0.1f;
float b = 0.2f;
float c = a + b;
System.out.println("a = " + a);
System.out.println("b = " + b);
System.out.println("c = a + b = " + c);
double x = 1.0 / 0.0;
double y = -1.0 / 0.0;
double z = 0.0 / 0.0;
System.out.println("x = 1.0 / 0.0 = " + x);
System.out.println("y = -1.0 / 0.0 = " + y);
System.out.println("z = 0.0 / 0.0 = " + z);
}
}
我们可以看到 IEEE 754 标准中的浮点数表示和运算:
- 单精度浮点数的加法:变量 a 和 b 分别存储了 0.1 和 0.2,它们的和 c 等于 0.3。由于浮点数表示的精度限制,c 的实际值可能与理论值略有误差。
- 特殊值:变量 x、y 和 z 分别存储了正无穷(+∞)、负无穷(-∞)和非数值(NaN)。这些特殊值是由除法运算产生的,当被除数为 0 或结果无法表示时,会返回相应的特殊值。
38.super
可用于调用父类的方法或者字段。
class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
public void eat() {
System.out.println(name + " is eating.");
}
}
public class Dog extends Animal {
public Dog(String name) {
super(name); // 调用父类的构造方法
}
public void bark() {
System.out.println(name + " is barking.");
}
public void eat() {
super.eat(); // 调用父类的方法
System.out.println(name + " is eating bones.");
}
}
39.switch
用于根据某个变量的值选择执行不同的代码块。switch 语句通常与 case 和 default 一起使用。每个 case 子句表示一个可能的值和对应的代码块,而 default 子句用于处理不在 case 子句中的值。
public class Main {
public static void main(String[] args) {
int dayOfWeek = 3;
switch (dayOfWeek) {
case 1:
System.out.println("Monday");
break;
case 2:
System.out.println("Tuesday");
break;
case 3:
System.out.println("Wednesday");
break;
case 4:
System.out.println("Thursday");
break;
case 5:
System.out.println("Friday");
break;
case 6:
System.out.println("Saturday");
break;
case 7:
System.out.println("Sunday");
break;
default:
System.out.println("Invalid day");
break;
}
}
}
在这个示例中,我们定义了一个名为 dayOfWeek 的整数变量,并赋予了一个值。然后,我们使用 switch 语句根据 dayOfWeek 的值来输出对应的星期几。每个 case 子句表示 dayOfWeek 可能的值,后面紧跟着要执行的代码。使用 break 语句跳出 switch 语句,避免执行其他 case 子句的代码。如果 dayOfWeek 的值不在 case 子句中,default 子句将被执行。
40.synchronized
用于指定多线程代码中的同步方法、变量或者代码块。
public class MyClass {
private int count;
public synchronized void increment() {
count++; // 同步方法
}
public void doSomething() {
synchronized(this) { // 同步代码块
// 执行一些需要同步的操作
}
}
}
41.this
可用于在方法或构造方法中引用当前对象。
public class MyClass {
private int num;
public MyClass(int num) {
this.num = num; // 使用 this 关键字引用当前对象的成员变量
}
public void doSomething() {
System.out.println("Doing something with " + this.num); // 使用 this 关键字引用当前对象的成员变量
}
public MyClass getThis() {
return this; // 返回当前对象本身
}
}
在这个示例中,MyClass 类有一个私有成员变量 num,并定义了一个构造方法、一个方法和一个返回当前对象的方法。在构造方法中,使用 this 关键字引用当前对象的成员变量,并将传入的参数赋值给该成员变量。在方法 doSomething()
中,使用 this 关键字引用当前对象的成员变量,并输出该成员变量的值。在方法 getThis()
中,直接返回当前对象本身。
42.throw
主动抛出异常。
public class MyClass {
public void doSomething(int num) throws Exception {
if (num < 0) {
throw new Exception("num must be greater than zero"); // 手动抛出异常
}
// 执行一些操作
}
}
43.throws
用于声明异常。
public class MyClass {
public void doSomething(int num) throws Exception {
if (num < 0) {
throw new Exception("num must be greater than zero"); // 手动抛出异常
}
// 执行一些操作
}
}
44.transient
修饰的字段不会被序列化。
public class MyClass implements Serializable {
private int id;
private String name;
private transient String password;
public MyClass(int id, String name, String password) {
this.id = id;
this.name = name;
this.password = password;
}
// 省略 getter 和 setter 方法
@Override
public String toString() {
return "MyClass{" +
"id=" + id +
", name='" + name + '\'' +
", password='" + password + '\'' +
'}';
}
}
在这个示例中,MyClass 类实现了 Serializable 接口,表示该类的对象可以被序列化。该类有三个成员变量,分别是 id、name 和 password。其中,password 成员变量被标记为 transient,表示在序列化过程中忽略这个成员变量。
45.try
用于包裹要捕获异常的代码块。
try {
// 可能抛出异常的代码
int result = 1 / 0;
} catch (Exception e) {
// 异常处理代码
e.printStackTrace();
}
46.void
用于指定方法没有返回值。
public void doSomething() {
// 方法体
}
47.volatile
保证不同线程对它修饰的变量进行操作时的可见性,即一个线程修改了某个变量的值,新值对其他线程来说是立即可见的。
public class MyThread extends Thread {
private volatile boolean running = true;
@Override
public void run() {
while (running) {
// 线程执行的代码
}
}
public void stopThread() {
running = false;
}
}
在这个示例中,MyThread 类继承了 Thread 类,重写了 run()
方法。MyThread 类有一个成员变量 running,被标记为 volatile,表示这个变量是共享的,可能会被多个线程同时访问。在 run()
方法中,使用 while 循环检查 running 变量的值,如果 running 为 true,就继续执行循环体中的代码。在另一个方法 stopThread()
中,将 running 变量的值设置为 false,表示需要停止线程。
48.while
如果循环次数不固定,建议使用 while 循环。
int i = 0;
while (i < 10) {
System.out.println(i);
i++;
}
Java中的关键字常用的就是这48个,除了这48个关键字,Java中还有两个非常特殊的保留字(goto 和 const),它们不能在程序中使用。具体介绍如下:
49.goto(保留字)
goto 在 C语言中叫做‘无限跳转’语句,在 Java 中,不再使用 goto 语句,因为无限跳转会破坏程序结构。但 Java 中确实可以使用标签(label)与 break 和 continue 语句结合来实现类似 goto 的跳转功能。以下是一个简单的示例:
public class LabelDemo {
public static void main(String[] args) {
outerLoop:
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (i == 1 && j == 1) {
System.out.println("跳过 outerLoop 中的当前迭代");
continue outerLoop;
}
System.out.println("i: " + i + ", j: " + j);
}
}
System.out.println("结束");
}
}
在这个示例中,我们使用了两层嵌套循环。外层循环有一个名为 outerLoop 的标签。当 i 等于 1 且 j 等于 1 时,我们使用 continue outerLoop 语句跳过外层循环中的当前迭代。这与 goto 的行为类似。
尽管可以使用标签实现类似 goto 的跳转功能,但这种用法在 Java 中仍然较少见,因为过度使用可能导致代码难以理解和维护。通常建议尽可能使用其他控制结构(如 if、for 和 while 语句)来组织代码。
以下是一个使用 if 和 for 语句替代标签跳转的示例。在这个示例中,我们使用了一个布尔变量 skipIteration 来决定是否跳过外层循环的当前迭代:
public class IfForDemo {
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
boolean skipIteration = false;
for (int j = 0; j < 3; j++) {
if (i == 1 && j == 1) {
System.out.println("跳过外层循环中的当前迭代");
skipIteration = true;
break;
}
System.out.println("i: " + i + ", j: " + j);
}
if (skipIteration) {
continue;
}
}
}
}
在这个示例中,当 i 等于 1 且 j 等于 1 时,我们将 skipIteration 设置为 true,然后使用 break 语句跳出内层循环。在外层循环中,我们检查 skipIteration 变量的值,如果为 true,则跳过外层循环的当前迭代。
50.const(保留字)
const在C语言中是声明常量的关键字,在 Java 中可以使用 public static final
三个关键字的组合来达到常量的效果。
public class Circle {
public static final double PI = 3.14159;
public static double calculateArea(double radius) {
return PI * radius * radius;
}
}
在这个示例中,我们使用 public static final 关键字组合定义了一个名为 PI 的常量。因为它是 public 的,所以其他类可以访问这个常量。因为它是 static 的,所以它与类关联,而不是类的实例。因为它是 final 的,所以它的值不能被更改。
😃😃😃