Java 中静态和动态的区别

2025年7月7日 | 阅读 8 分钟

Java 是一种以其可移植性和灵活性而闻名的编程语言,它包含了两个经常让开发人员感到困惑的基本概念:静态 和 动态

静态意味着某事物属于类本身,而不是类的实例(对象)。它也称为编译时行为。动态通常指在程序执行期间发生的行为。它也称为运行时行为。静态和动态概念都可以应用于方法、变量和代码块。

Java 中的静态

静态变量

在 Java 中,`static` 关键字标记类级别的成员,这意味着该变量在类的所有实例之间共享。静态变量的初始化仅在类加载到内存时发生一次。

示例

编译并运行

输出

2

解释:在这里,每次实例化 `Main` 对象时,静态变量 `totalItems` 都会递增,并且其值在所有实例之间共享。

静态方法

静态方法与其变量对应物一样,属于类而不是实例。它们使用类名调用,无需实例化对象。请注意,静态方法不能被重写。

示例

编译并运行

输出

8

静态方法通常用于实用函数,例如数学计算或辅助方法。

静态代码块

静态代码块提供了一种执行仅在类加载时需要运行一次的代码的机制。这些代码块特别适用于初始化静态变量或执行需要一次性设置的任务。

示例

编译并运行

输出

Configuration loaded.

静态代码块确保在加载类时执行指定的任务,从而加强了一次性初始化的概念。

Java 中的动态

动态变量

与静态变量相反,动态变量与类的实例相关联。每个对象都拥有自己的动态变量副本,在对象级别封装状态。

示例

编译并运行

输出

1000
2000

在这种情况下,每个 `Main` 对象都有自己的 `accountBalance`,允许独立的状态和封装。

动态方法(实例方法)

动态方法,也称为实例方法,作用于实例变量,并有助于 Java 程序的模块化和封装。

示例

编译并运行

输出

78.53981633974483
153.93804002589985

在这里,`calculateArea()` 方法作用于实例变量 `radius`,展示了实例方法的动态性。

Java 中的静态与动态

方面静态动态
关联 (Association)与类本身相关联。静态成员是类级别的实体,在所有实例之间共享。类级别的关联允许所有对象之间保持一致。与类的实例(对象)相关联。动态成员分别属于每个对象,封装了特定于实例的特征。每个对象都有自己的一组动态成员。
声明使用 `static` 关键字声明。`static` 关键字置于静态变量和方法的声明之前,明确表示它们属于类。正常声明。动态成员隐式地与实例相关联;因此,它们的声明不需要特殊的关键字。
内存分配在类加载期间分配一次内存。静态成员共享在类加载阶段分配的公共内存空间。所有实例都可以访问此共享内存空间。为每个实例单独分配内存。动态成员为每个实例分配专用内存。这种单独的内存分配确保了对象数据的隔离。
初始化在类加载时初始化一次。静态变量在类加载过程中初始化。如果存在静态代码块,则在初始化期间执行一次,为一次性设置提供空间。在创建对象时初始化。动态变量在使用 `new` 关键字实例化对象时进行初始化。构造函数负责在对象创建期间初始化动态成员。
访问使用类名访问。静态成员直接通过类名访问,使其独立于对象实例。动态成员使用特定对象的引用来访问。这需要创建对象才能访问和修改动态成员。
可修改性在所有实例之间共享。对静态成员的更改会反映在类的所有实例中。静态成员有助于类之间的共享状态。特定于实例,每个对象都有自己的副本。动态成员特定于每个对象,允许单独管理状态。对动态成员的更改仅影响它们所属的实例。
用途用于实用方法、常量和共享资源。静态成员非常适合所有实例通用的功能,例如实用方法、常量和共享资源。用于面向对象的行为,封装实例状态。动态成员用于特定于单个对象的行为,在实例中封装状态。实例方法作用于动态变量。
绑定时间早期(编译时):编译时是静态方法固定的时间。这使得编译器能够进行内联等优化。晚期(运行时):多态性由在运行时解析并可以重写的方法支持。
继承行为静态方法不存在多态性。它们可以被隐藏,但不能被重写。实例方法支持多态性。子类可以重写它们。
接口用法实现类不会继承静态方法,并且可以在 Java 8 及更高版本中的接口中使用。接口继承了需要实现的实例方法(如果它们是抽象的)。
线程同步当被多个线程访问时,由于数据在实例之间共享,因此需要显式同步。只要没有多个线程共享同一个对象,发生线程问题的可能性就较小。数据对每个实例都是唯一的。
序列化由于静态成员是类的一部分而不是特定对象,因此它们不会被序列化。序列化对象时,实例成员也会被序列化。

何时在 Java 中使用静态?

  • 共享资源:当一个变量或方法应该在类的所有实例之间共享时,使用静态。
  • 一次性设置:利用静态代码块来执行在类加载期间需要一次性初始化的任务。
  • 实用方法:使用静态方法来执行不依赖于特定于实例状态的实用功能。

何时在 Java 中使用动态?

  • 特定于实例的状态:为特定于单个实例的变量和方法选择动态。
  • 面向对象范例:将动态方法用于对象的固有状态和功能的行为。
  • 封装:利用动态元素来封装对象中的状态。

静态示例

示例

编译并运行

输出

Enter a value:
5
Static block executed.
Static variable after modification: 5

动态示例

示例

编译并运行

输出

Enter an initial value for the dynamic variable:
10
Enter an increment value:
3
Dynamic variable: 13

在这个动态示例中,系统提示用户输入动态变量的初始值和增量值。然后根据用户的输入修改动态变量,并通过动态方法显示其值。Main 类的每个实例都有自己的动态变量副本。

在 Java 编程领域,静态和动态不是对立的力量,而是为软件开发交响乐做出贡献的和谐元素。理解何时使用每种概念就像指挥一场交响乐,以一种产生连贯高效结果的方式编排元素。

通过掌握 Java 中静态和动态的细微差别,开发人员可以编写出不仅功能强大,而且优雅的代码,为可扩展且可维护的应用程序奠定基础。静态与动态之间的舞蹈是一种平衡的芭蕾,掌握它将释放 Java 开发的真正潜力。

Java 静态与动态选择题

1. 关于静态方法,以下哪项是不正确的?

  1. 它们可以访问静态变量
  2. 它们可以被重写
  3. 它们属于类,而不是实例
  4. 它们可以在不创建对象的情况下被调用
 

答案: b)

解释:静态方法在编译时绑定,不能像实例方法那样被重写。


2. Java 中的动态是什么意思?

  1. 编译时执行
  2. 运行时执行
  3. a 和 b 都是
  4. 以上都不是
 

答案:b)

解释:动态通常指在程序执行期间发生的行为。


3. 如果需求是共享资源,您将使用哪种概念?

  1. 动态概念
  2. 静态概念
  3. 重载概念
  4. 以上都不是
 

答案:b)

解释:当一个变量或方法应该在类的所有实例之间共享时,使用静态。


4. 在静态上下文中,内存是 ___________ 分配的?

  1. 为每个实例单独分配
  2. 类加载后一次
  3. 类加载期间一次
  4. 以上都不是
 

答案:c)

解释:内存是在类加载期间分配一次的。静态成员共享在类加载阶段分配的公共内存空间。所有实例都可以访问此共享内存空间。


5. 动态成员可以使用 __________ 访问。

  1. 类名
  2. 对象引用
  3. 包名
  4. 以上都不是
 

答案:b)

解释:动态成员使用特定对象的引用来访问。这需要创建对象才能访问和修改动态成员。