sunny123456

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 :: 管理 ::

java中static和const和final的区别

static 关键字

static 关键字用于声明类的成员(方法或变量)为静态成员。静态成员属于类本身,而不是类的实例。换句话说,静态成员可以通过类名直接访问,而不需要实例化对象。

  • 静态变量:属于类的所有对象共享,类的所有实例共享相同的内存位置。
  • 静态方法:可以在没有创建对象的情况下直接调用。
  • 静态块:在类加载时执行一次,用于初始化类的静态成员。
  • 编译时机static 关键字主要在编译时确定。它告诉 JVM,该成员属于类而非实例,因此不需要通过对象来访问。static 修饰的变量和方法会被加载到 方法区 中的 类的结构部分
  • 内存存储位置static 成员存储在 方法区 中的 类的静态变量区。每个类只有一个静态变量区,所有实例共享这部分内存。静态方法也存储在方法区的 方法区(Method Area) 中。

count 是静态变量,在两个 Counter 对象中共享,displayCount 是静态方法,可以通过类名直接调用。

  1. class Counter {
  2. static int count = 0; // 静态变量
  3. Counter() {
  4. count++; // 每次创建对象时,静态变量 count 会增加
  5. }
  6. static void displayCount() {
  7. System.out.println("Count: " + count); // 静态方法可以直接访问静态变量
  8. }
  9. }
  10. public class Main {
  11. public static void main(String[] args) {
  12. Counter c1 = new Counter();
  13. Counter c2 = new Counter();
  14. Counter.displayCount(); // 调用静态方法,输出 Count: 2
  15. }
  16. }
java
运行

final 关键字

final 是一个多用途的关键字,它可以用于变量、方法和类的定义,分别具有不同的含义。

  • 用于变量:声明为 final 的变量是常量,一旦赋值后不可更改(不可重新赋值)。
  • 用于方法:声明为 final 的方法不能被子类重写。
  • 用于类:声明为 final 的类不能被继承。
  • 编译时机final 关键字的使用在编译时就确定了变量、方法或类的行为。例如,如果一个方法被声明为 final,编译器会禁止任何子类重写该方法;如果一个类被声明为 final,编译器会禁止任何子类继承该类。对于变量,final 确保该变量一旦赋值后不可修改。
  • 内存存储位置
    • final 变量:常量(final 变量)通常在 方法区 中的 常量池(Constant Pool) 中存储。如果是局部变量,存储在栈中。
    • final 类和方法:存储在 方法区 中的 类的结构部分final 类和方法不会被继承或重写,因此它们在运行时不需要动态解析。

PI 被声明为 final,因此它的值不能更改。

  1. // final 变量
  2. class Circle {
  3. final double PI = 3.14159; // 常量,值不可更改
  4. void calculateArea(double radius) {
  5. double area = PI * radius * radius; // 使用常量
  6. System.out.println("Area: " + area);
  7. }
  8. }
  9. public class Main {
  10. public static void main(String[] args) {
  11. Circle circle = new Circle();
  12. circle.calculateArea(5);
  13. // PI = 3.14; // 编译错误,无法修改 final 变量的值
  14. }
  15. }
java
运行

const 关键字

Java 中,const 是一个保留关键字,但它并没有在语言中实现功能,实际上 Java 中并不使用 const 来定义常量。Java 提供了 final 来替代 const 的功能。

  • const 在 Java 中没有实现任何功能。
  • const 关键字保留用于未来可能的用途,但目前不被使用。
  • 常量在 Java 中应该使用 final 关键字来定义。
  • 编译时机:虽然 const 是 Java 中的保留关键字,但它并没有被实现。实际上,Java 没有使用 const 来定义常量。在 Java 中,我们通常使用 final 来定义常量。
  • 内存存储位置:由于 const 不被实际使用,它不会在内存中占用任何空间。任何常量都应该使用 final 来定义,并存储在 方法区的常量池 或堆栈中。

使用 const 会导致编译错误,因为 const 在 Java 中并没有实际作用。 

  1. // const 在 Java 中并不使用
  2. public class Main {
  3. public static void main(String[] args) {
  4. // const int x = 10; // 编译错误,const 不被使用
  5. }
  6. }
java
运行
特性staticfinalconst
定义用于类的成员(方法、变量)指定该成员为静态的用于变量、方法、类,表示常量、不允许修改或重写目前在 Java 中没有实现
使用场景当需要共享数据或功能时使用用于常量、禁止继承/重写的方法、不可修改的变量Java 中不使用 const
作用域静态成员属于类,而不是实例对象变量不可修改,方法不可重写,类不可继承不被使用
示例static int count;final int x = 10;不支持
静态方法静态方法可以在没有实例化对象的情况下直接调用不适用不适用
继承/重写静态成员可以被继承,但不可以被重写final 方法不能被重写,final 类不能被继承不适用
关键字编译时机内存存储位置说明
static编译时方法区 中的 类的静态变量区,静态方法也存储在方法区中static 成员属于类而非实例,所有实例共享这部分内存
final编译时方法区的常量池堆栈(针对局部变量)final 变量会存储在常量池中,final 方法和类存储在方法区
const编译时不会被使用const 是保留关键字,Java 没有实际应用,通常用 final 代替

完整示例

  1. class Person {
  2. static String species = "Homo sapiens"; // 静态变量
  3. final String name; // 常量,必须在构造方法中初始化
  4. Person(String name) {
  5. this.name = name;
  6. }
  7. // final 方法,不能被子类重写
  8. final void showDetails() {
  9. System.out.println("Name: " + name + ", Species: " + species);
  10. }
  11. }
  12. class Student extends Person {
  13. Student(String name) {
  14. super(name);
  15. }
  16. // 编译错误,无法重写 final 方法
  17. // void showDetails() {
  18. // System.out.println("Student: " + name);
  19. // }
  20. }
  21. public class Main {
  22. public static void main(String[] args) {
  23. Person person = new Person("Alice");
  24. person.showDetails(); // 调用父类的 final 方法
  25. // 通过类名访问静态变量
  26. System.out.println("Species: " + Person.species);
  27. // 修改静态变量
  28. Person.species = "Homo erectus";
  29. System.out.println("Updated Species: " + Person.species);
  30. // name = "Bob"; // 编译错误,final 变量不可修改
  31. }
  32. }
java
运行

Java 内存区的详细说明

1.方法区(Method Area)
  • 存放内容:类的结构(包括类的元数据)、静态变量、常量池、方法代码等。
  • 静态成员和常量static 成员变量和 final 常量通常存储在方法区中。静态方法也存储在方法区。常量则会存放在类的常量池(Constant Pool)中。
2.堆(Heap)
  • 存放内容:对象实例、数组、类的实例等。
  • final 变量(如果是对象引用):如果 final 变量是引用类型,则它的引用会存放在栈中,但对象本身会存放在堆中。
3.栈(Stack)
  • 存放内容:局部变量、方法调用信息、操作数栈等。
  • final 局部变量:局部变量(如方法参数)如果是 final,则存储在栈上。
4.程序计数器(Program Counter Register)
  • 存放内容:每个线程都有一个程序计数器,指向当前执行的字节码指令。
  • final 修饰的局部变量(参数):存储在栈上,而栈本身不直接与程序计数器相关联。
5.本地方法栈(Native Method Stack)
  • 存放内容:存放 native 方法的调用信息。

            </div>

原文链接:https://blog.csdn.net/yyfloveqcw/article/details/144936639

posted on 2026-02-04 11:34  sunny123456  阅读(0)  评论(0)    收藏  举报