【java进阶01:final关键字】final修饰的变量只能赋一次值

news2024/11/25 1:02:46

目录

final修饰的类无法继承。

final修饰的引用一旦指向某个对象,则不能再指向其他对象,但该引用指向的对象内部的数据是可以修改的。​编辑

final修饰的实例变量必须手动初始化,因为系统不会赋默认值,强制手动赋值,否则报错

final修饰的实例变量一般和static联合使用,成为常量。


  1. final修饰的类无法继承。

    final修饰的方法无法覆盖

    final修饰的变量只能赋一次值(final修饰的变量无法改变。)

    /*
        final
            1、final是java语言中的一个关键字。
    ​
            2、final表示:
                最终的,不可变的。
                
            3、★final修饰的变量
                final修饰的局部变量,赋值后不能重新赋值(无法修改) /final修饰的变量只能赋一次值
    ​
            4、★final修饰的方法
                final修饰的方法,在子类中无法被覆盖/重写
    ​
            5、★final修饰的类
                final修饰的类无法被继承
    ​
            6、final不控制调用,表示被修饰的东西不能改了,与能不能调用没有关系。
     */
    public class FinalText01 {
        public static void main(String[] args) {
    ​
            //局部变量
            int i = 100;
            final int k = 200;
    ​
            //重新赋值
            i = 200;
            //Error: 无法为最终变量k分配值
            //k = 2000;    final修饰的变量赋值后不能再修改值
    ​
            final int l;
            //第一次赋值
            l = 1;
            //重新赋值
            //l = 11; //编译报错:Error: 可能已分配变量l
        }
    }
    ​
    //class A2{}
    final class A2{}    //A2不能有子孙(不能有子类),相当于绝育了。
    /*
        B2类可以继承A2类,等于对A2类的功能进行扩展,如果不希望别人对A2类进行扩展,可以为A2加final关键字
        这样其他类就无法继承A2类了。
        错误: java: 无法从最终A2进行继承
    ​
     */
    //class B2 extends A2{}
    ​
    ​
    //Error: 无法从最终java.lang.String进行继承,String类前有final修饰,
    //class MyString extends String{}
    ​
    class C{
        public final void doSome(){
            System.out.println("C doSome");
        }
    }
    class D extends C{
        /*
            Error: D中的doSome()无法覆盖C中的doSome()    被覆盖的方法为final
    ​
            public void doSome(){
                System.out.println("D doSome");
            }
         */
    }
  2. final修饰的引用一旦指向某个对象,则不能再指向其他对象,但该引用指向的对象内部的数据是可以修改的。

    /*
        final修饰的变量,如果这个变量是一个“引用”会怎么样?
            注意:final修饰的变量只能赋一次值(万变不离其宗)
            “引用”实际上保存的是一个对象的“内存地址”,加上final之后,表示:这个“引用”保存的“内存地址”不可以再改变
    ​
            final修饰的“引用” :
                该引用只能指向一个对象,并且永远只指向该对象,无法再指向其他对象。
                并且在该方法执行过程中,该引用指向对象之后,该对象不会被垃圾回收器回收
                直到main方法结束之后,才会释放空间。
    ​
                虽然final的引用指向对象A之后,不能再重新指向对象B。但是对象A内部的数据可以被修改。
     */
    public class FinalText02 {
        public static void main(String[] args) {
            //这里的p1、p2在main方法中,实际上也是一个局部变量。
            //创建对象
            Person1 p1 = new Person1(10);
            System.out.println(p1.age);
            //修改
            p1 = new Person1(20);
            System.out.println(p1.age);
    ​
            //final修饰的引用
            final Person1 p2 = new Person1(30);
            //重新赋值(重新分配一个内存地址)  编译报错:Error: 无法为最终变量p2分配值
            //p2 = new Person1(30);
            //可以为p2赋一个null吗? 编译爆错:Error: 无法为最终变量p2分配值
            //p2 = null;
    ​
            //虽然不再指向其他对象,但是对象中保存的数据可以修改。
            p2.age = 88;
            System.out.println(p2.age);
        }
    }
    class Person1{
        int age;
        public Person1(){
    ​
        }
        public Person1(int age){
            this.age = age;
        }
    }
  3. final修饰的实例变量必须手动初始化,因为系统不会赋默认值,强制手动赋值,否则报错

    /*
    ​
            ★ final修饰的变量只能赋值一次。
            实例变量如果没有手动赋值,系统会赋默认值
    ​
        final 修饰的实例变量
            经过测试:
            结论:final修饰的实例变量,系统不会再赋默认值,要求程序员必须手动赋值。
            在定义实际变量时在后面直接赋值可以   :final int i =10;
            在构造方法中赋值也可以:
                final int i;
                无参:
                    public User(){
                        this.i = 10;
                    }
                有参:
                    public User(int i){
                        this.i = i;
                    }
                ★这两个构造方法有一个即可,共存也可以的。调用时:
                    调用无参的,该对象的i值就是:10
                    调用有参的,该对象的i值是调用时传递进去的i值。
    ​
                ★虽然系统赋默认值是:0/0.0/null等,但是不意味着这些值不可以赋值给变量
                  不手动赋值,等系统赋默认值,实际报错:Error: 变量 weight 未在默认构造器中初始化
                    也就是说系统实际上不会为final修饰的实例变量赋默认值,同时强制手动赋值。
     */
    public class FinalText03 {
        public static void main(String[] args) {
            User u = new User(60);
            System.out.println(u.weight);
        }
    }
    class User{
        //final修饰的实例变量
        //编译报错:Error: 变量 age 未在默认构造器中初始化
        //final int age;
        //结论:final修饰的实例变量,系统不会再赋默认值,要求程序员必须手动赋值。
    ​
        //编译通过,因为这里手动赋值了。
        final double height =1.8 ;
    ​
        //如果定义的时候不赋值,可以在无参的构造方法里手动为它赋值。
        //因为系统赋默认值的时候是在构造方法执行时赋值,所以只要赶在系统赋默认值之前为final修饰的变量赋值就可以
        //但是不能等系统赋默认值,因为系统看到你用final修饰了实例变量之后,不再为变量赋默认值的同时强制手动赋值。
        // 如果构造方法里不手动赋值,就会报错:weight 未在默认构造器中初始化
        final double weight;
    ​
        //构造方法
        public User(){
            this.weight = 60;
        }
    ​
        //有参构造
        public User(double weight){
            this.weight = weight;//这个也算是赋值了,没有采用系统默认值。在调用此有参构造方法时会传递参数进来
                                 //传递一个参数赋值给weight。
        }
    }
  4. final修饰的实例变量一般和static联合使用,成为常量。

    /*
        final修饰的实例变量,必须手动赋值
        final修饰的变量,只能赋值一次。
    ​
        final修饰的实例变量一般添加static修饰
    ​
        结论:
            static final联合修饰的变量为“常量”
            常量名建议全部大写,每个单词之间用下划线(_)连接。
    ​
        常量
            实际上与静态变量一样,区别在于:常量的值不能改变。
    ​
            常量与静态变量,都是存储在方法区中,并且都是在类加载的时候初始化。
    ​
            常量一般都是公共的:public 的
            原因:常量不能修改,如封装就是为了不被修改。所以常量公开也没关系,因为他改不了。
     */
    public class FinalText04 {
        public static void main(String[] args) {
            System.out.println(Chinese.COUNTRY);
            //编译报错:Error:无法为最终变量COUNTRY分配值
            //Chinese.COUNTRY = "English";  //常量无法重新赋值。
        }
    }
    class Chinese{
        //身份证号,每个人都不一样,对象级别
        String idCard;
        //姓名,不同对象不同姓名。
        String name;
        //国家的值是一个固定值:“中国”
        //实例变量在堆中,一个对象一份,100个对象100份。
        //既然这里的值不会改变,还有必要声明为实例变量吗?
        //实例变量既然使用final修饰,说明该实例变量值不会随着对象的变化而变化。
        //final String country = "中国";
    ​
            //i永远都是10,创建100个对象,i也是10.
            //i是10永远不会发生改变,既然这样,没必要声明为实例变量,最好声明为静态,节省内存。
            //final int i = 10;
            //加上static以后,static与final联合使该变量变为“常量”,不再是每个对象一份。
            static final int I  = 10;
    ​
    ​
        //static final String COUNTRY = "中国";
        public static final String COUNTRY = "中国";
    }
    class MyMash{
        public static final double PI = 3.1415926;
    }

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【router-view】切换组件 深刻理解用法 vue的设计思想

之前学的时候没学明白,导致写项目有些功能的实现上走了歪路。 今天询问了学长,更加深刻的理解的Vue的设计思想。 因为vue是单页面应用,所以学会用router-view来切换频繁变化的地方的组件是非常重要的。 之前,我的一个主页组件由…

Xshell远程连接配置 Ubuntu 18.04.6 + Anaconda + CUDA + Cudnn + Pytorch(GPU+CPU)

Xshell远程连接进行Ubuntu的Pytorch配置写在最前面参考Xshell常用命令Ubantu检查系统的各项配置查看ubuntu系统的版本信息查看Linux的内核版本和系统是多少位的Ubuntu版本各种验证禁用nouveau安装显卡驱动卸载显卡驱动安装显卡驱动加入PPA,然后更新库方法一&#xf…

maven离线模式及设置

maven离线模式及设置 maven离线模式使用场景? 遇到的问题: 最近遇到个项目支持,他在打jar包的时候,总是去网上下载 maven依赖,不去找我本地仓库的,就比较头大,原因不明 现在需求:就…

SpringBoot 玩一玩代码混淆,防止反编译代码泄露

编译 简单就是把代码跑一哈,然后我们的代码 .java文件 就被编译成了 .class 文件 反编译 就是针对编译生成的 jar/war 包 里面的 .class 文件 逆向还原回来,可以看到你的代码写的啥。 比较常用的反编译工具 JD-GUI ,直接把编译好的jar丢进…

java项目-第144期ssm农产品供销服务系统-java毕业设计_计算机毕业设计

java项目-第144期ssm农产品供销服务系统-java毕业设计_计算机毕业设计 【源码请到资源专栏下载】 今天分享的项目是《ssm农产品供销服务系统》 该项目分为2个角色,管理员和用户。 用户可以浏览前台,包含功能有: 首页、农产品、农产品资讯、我的、跳转到后…

JavaScript DOM中获取元素、事件基础、操作元素、节点操作

目录 JavaScript事件三要素 常见的事件​编辑 2、执行事件的步骤: 1. 获取元素 1.1 方式 1.1.1 根据ID获取 1.1.2 根据标签名获取 1.1.3 通过html5新增的方法获取 1.1.4 特殊元素获取 2. 事件基础 2.1 事件三要素 2.1.1 事件源 2.1.2 事件类型 2.1.3…

如何使用Spring Security控制会话

在 Spring 安全教程的这篇文章中,我们将讨论Spring 安全会话管理。我们将讨论 Spring 安全性的独特功能,这有助于我们高效和安全的会话管理。 春季安全会议 本文将讨论安全会话管理以及 spring 安全性如何帮助我们控制 HTTP 会话。Spring 安全性使用以…

1.4_29 Axure RP 9 for mac 高保真原型图 - 案例28【中继器-后台管理系统6】功能-原位修改数据

相关链接 目录Axure中文学习网AxureShopAxureShop-QA 案例目标1. 了解使用中继器,弹窗修改数据的实现方式 一、成品效果 Axure Cloud 案例28【中继器 - 后台管理系统6】功能-原位修改数据 版本更新一、修改功能   1.1 文本框:点击数据位置&#xff…

InternImage

终于有对抗Transformer 的了~~ 来自浦江实验室、清华等机构的研究人员提出了一种新的基于卷积的基础模型,称为 InternImage,与基于 Transformer 的网络不同,InternImage 以可变形卷积作为核心算子,使模型不仅具有检测和分割等下游…

MySQL删除表数据总结(DELETE、TRUNCATE、DROP)

(1)当我们不再需要该表时,使用DROP,会连表一起删掉,无法找回。速度很快。 DROP TABLE web_tbl_search;(2)保留表结构,只删除表数据,使用TRUNCATE,数据删除后…

【unCloud】在使用uni-admin时遇到的问题(原uniCloud-admin)

目录一、前言二、遇到的几个小问题问题一:可登录应用解决方法、步骤一、前言 这是我跟着官方的教学视频学习时遇到的一切小问题,由于我是初学,也没什么很多Vue一类的基础,所以学起来可能才会觉得这些是问题,但是也暂做…

得物视频编辑工具优化全指南

一、背景介绍 随着5G网络的推广和网络带宽的提升,视频成为互联网用户主要的消费载体,用户通过短视频来分享和浏览信息。由此视频的编辑功能越来越重要、越来越普遍。视频编辑的APP也如雨后春笋般涌现。 更好地推动得物App社区业务的发展,得…

测试日常工作中需要具备哪些知识和能力,在需求评审时需要考虑哪些方面,在技术方面评审时需要考虑哪些方面,从什么方面进行设计测试用例

前几天同事分享了一波作为测试需要具备哪些能力,测试用例需要从哪些方面进行设计,我把他分享的内容拷贝了一波,作为以后在测试过程中的参考。 首先需求评审、技术方案评审、测试用例评审三者的关系 一开始,我每次设计测试用例都是…

操作系统 | 实验八 文件管理

一、实验目的 掌握文件的存取方法;掌握文件的逻辑结构和物理结构;掌握存储空间的分配和回收;掌握磁盘管理与调度。 二、实验内容 用程序模拟磁盘的调度过程,并计算各磁盘调度算法包括先来先服务算法、最短寻道时间优先算法、扫…

【大根堆 Java】使用优先队列+HashMap 解决前 K 个高频元素问题

一、题目描述 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 示例 二、思路 本题我们主要完成两个步骤: 统计出每个元素出现的次数找出出现次数最多的前 K 个元素 对第一个步骤&#xf…

IPWorks S/MIME Delphi Edition

IPWorks S/MIME是一套用于电子邮件加密和文档安全的综合组件。IPWorks S/MIME使用公钥密码标准(PKCS)实现加密和解密的S/MIME标准。 IPWorks S/MIME包括通用的S/MIME组件以及支持S/MIME的IPWorks POP3、IMAP、SMTP、FileMailer和HTMLMailer组件版本。还…

【MMDet】提交PR的学习笔记

官方文档 关于如何向MMDet提交PR,请参考mmcv的文档《拉取请求 — mmcv 1.6.1 文档》 1. Fork最新代码库 当第一次提PR时,需要复刻OpenMMLab代码库,点击 GitHub 页面右上角的Fork按钮即可 将复刻的代码库克隆到本地 git clone fork_mmdet…

trunc函数与truncate函数的一点区别

Oracle的trunc函数与truncate函数都可以对数值进行截取操作 -- 首先看对数值进行截取操作 SELECT TRUNCATE(122.123, 4) from dual; # 122.123 SELECT TRUNCATE(122.123, 3) from dual; # 122.123 SELECT TRUNCATE(122.123, 2) from dual; # 122.12 SELECT TRUNCATE(122.123, 1…

vue3中使用element plus

1、先安装node.js node.js的安装_西瓜君的代码的博客-CSDN博客 2、安装vue-cli vue-cli的安装_西瓜君的代码的博客-CSDN博客 3、安装element-plus Element UI 安装_西瓜君的代码的博客-CSDN博客 4、idea中使用vue3 在idea中使用vue3_西瓜君的代码的博客-CSDN博客 5、 加入 impo…

分享从零开始学习网络设备配置--2.5 提高骨干链路带宽(链路聚合)

任务描述 某公司的网络中心为了接入网络稳定性,在汇聚层交换机的连接连路上使用了多条冗余链路,同时,为了增加带宽,多条冗余链路之间实现端口聚合,提高骨干链路的带宽,这样可以实现链路之间的冗余和备份效果…