Java面向对象(高级)-- final关键字的使用

news2024/10/1 19:28:19

文章目录

  • 一、 final的意义
  • 二、 final的使用
    • (1) final修饰类
    • (2) final修饰方法
    • (3) final修饰变量
      • 1. 修饰成员变量
        • 1.1 举例1
        • 1.2 举例2
      • 2. 修饰局部变量
        • 2.1 举例1
        • 2.2 举例2
    • (4)final搭配static
    • (5)总结
  • 三、 笔试题
    • (1)题1
    • (2)题2

一、 final的意义

final:最终的,不可更改的

final可以用来修饰的结构:类、方法、变量(成员变量、局部变量)

二、 final的使用

(1) final修饰类

表示这个类不能被继承,没有子类。提高安全性,提高程序的可读性。

例如:String类、System类、StringBuffer类

final class Eunuch{//太监类
	
}
class Son extends Eunuch{//错误
	
}

【举例】

正常情况下:

class A{

}

class B extends A{

}

若此时类A前面有final修饰,则B无法继承于A。如下:

image.png

💬什么样的需要用final去修饰呢?

功能不需要再被扩展了,比如String类、StringBuffer类、StringBuilder类。

image.png

会发现String加了一个final修饰:

public final class String...

这就意味着不能去声明一个类去继承于String。

image.png

Stirng类用final修饰,没有必要再进行功能的扩展。

(2) final修饰方法

表示这个方法不能被子类重写

例如:Object类中的getClass()

class Father{
	public final void method(){
		System.out.println("father");
	}
}
class Son extends Father{
	public void method(){//错误
		System.out.println("son");
	}
}

【举例】

正常情况下:

class C{
    public void method(){

    }
}

class D extends C{
    //此时可以
    public void method(){

    }
}

若是method()方法前面有final修饰,就不能重写了。如下:

image.png

💬什么样的方法需要用final去修饰呢?

这个方法已经设计的很完备了,也没有扩展的必要性,就可以用final修饰。

比如Object类中的getClass()

可以看一下,首先Ctrl+N调出搜索框,输入“Object”:

image.png

然后Ctrl+F12,搜索”getClass“:

image.png

然后可以看到getClass被final修饰,表示这个方法不能被重写了。这个方法的作用就是获取当前对象所属的类,不需要重写。

image.png

native表示调用的是本地的方法,会调用底层C、C++相关的代码。

native修饰的getClass()方法若是调用的时候,这个方法的栈帧会进入栈中,此时它入的栈叫做本地方法栈

这个本地方法,就是指native修饰的方法。

为啥getClass()方法没有方法体?因为它调用的是底层的C、C++,不是用java代码写的,所以没有方法体。它会链接到相关dll文件中的C、C++代码。

在早期,Java发展不成熟的时候,会用到native。

(3) final修饰变量

final修饰某个变量(成员变量或局部变量),一旦赋值,它的值就不能被修改,即常量,常量名建议使用大写字母。

例如:final double MY_PI = 3.14;

如果某个成员变量用final修饰后,没有set方法,并且必须初始化(可以显式赋值、或在初始化块赋值、实例变量还可以在构造器中赋值)

1. 修饰成员变量

1.1 举例1
public class FinalTest {
    public static void main(String[] args) {
        E e=new E();
        System.out.println(e.MIN_SCORE);    //可以调用
    }
}

class E{
    //成员变量
    final int MIN_SCORE=0;
}

常量MIN_SCORE可以被调用,但是不能更改:

image.png

若此时将常量的显示赋值删掉,发现不可以:

image.png

没有默认值吗?

对于final修饰的成员变量,这时候默认值就不好使了。即使想用默认值0,也需要写出来。


若用方法赋值,不可以:

image.png

方法需要用对象去调用,而调用对象的时候,这个值该有就应该得有了。

之前说过给类的实例变量赋值的位置,其中默认初始化、显示初始化、代码块中初始化、构造器中初始化,它们在造对象过程中实现;而通过“对象.属性”或“对象.方法”进行赋值的时候,对象已经有了。

现在我们给常量赋值,意思就是当创建完对象的时候,这些属性的值就应该要有了。

后续调用方法(比如setRight()方法),体现为修改这个值。

而在声明它的时候没有赋值,而在有了对象之后,方法里面又不能修改这个值。

image.png

当对象创建完,属性的值就应该确定下来了。

💬有哪些位置可以给成员变量赋值?

  • 显式赋值
  • 代码块中赋值
  • 构造器中赋值
class E{
    //成员变量
    //1.默认赋值--NO
    //final int MIN_SCORE;

    //2.显示赋值--YES
    final int MIN_SCORE=0;

    //3.代码块中赋值--YES
    final int MAX_SCORE;
    {
        MAX_SCORE=100;  //一旦赋值就不可以再次赋值
    }

    //4.构造器中赋值--YES
    final int LEFT;
    public E(){ //用此构造器造完对象LEFT就赋完值了
        LEFT=2;
    }

    public E(int left){ //不同构造器都需要对常量LEFT赋值,每造一个对象就会拥有一份LEFT,所以每个对象的LEFT可以不同,但是一旦赋值不可更改
        LEFT=left;
    }

    //5.方法赋值--NO
    /*final int RIGHT;    //没有在允许的位置赋值
    public void setRIGHT(int right){
        RIGHT=right;    //有了对象之后,不能在方法里面修改常量的值
    }*/
    
}
1.2 举例2
public final class Test {
    public static int totalNumber = 5;
    public final int ID;

    public Test() {
        ID = ++totalNumber; // 可在构造器中给final修饰的“变量”赋值
    }
    public static void main(String[] args) {
        Test t = new Test();
        System.out.println(t.ID);
    }
}

2. 修饰局部变量

final修饰局部变量:一旦赋值就不能修改

2.1 举例1
  • 方法内声明的局部变量:在调用局部变量前,一定需要赋值。而且一旦赋值,就不可更改。

【举例】

一般情况下:

class F{
    public void method(){
        int num=10;
        num++;
        System.out.println(num);
    }
}

若此时给num加上final,就不可以对num更改了:

image.png

如下:

class F{
    public void method(){
        final int num=10;   //写两行也没事,只要在调用它之前赋上值就行,一旦赋值不可更改
        //num++;
        System.out.println(num);
    }
}

  • 方法的形参:在调用此方法时,给形参进行赋值。而且一旦赋值,就不可更改。

【举例】

一般情况下:

class F{
    public void method(int num){
        num++;
        System.out.println(num);
    }
}

若是给num加上final,num就是一个常量,这个常量还是在调用的时候赋的,那么赋完值之后就不要更改了。

image.png

如下:

class F{
    public void method(final int num){
        //num++;    //赋完值之后就不要更改了
        System.out.println(num);
    }
}
2.2 举例2
public class TestFinal {
    public static void main(String[] args){
        final int MIN_SCORE ;
        MIN_SCORE = 0;
        final int MAX_SCORE = 100;
        MAX_SCORE = 200; //非法
    }
}
  • 错误演示:
class A {
    private final String INFO = "atyuyi";  //声明常量

    public void print() {
        //The final field A.INFO cannot be  assigned
        //INFO = "雨翼轻尘"; 
    }
}

(4)final搭配static

finalstatic搭配:修饰成员变量时(不能是局部变量,static不能修饰局部变量),此成员变量称为:全局常量。(只有一个且不能改变

这个变量兼具final和static的特点。

比如:Math的PI (直接通过类来调用且不能变)

在实际写代码的时候,若是在修饰类、修饰方法的时候忘记使用不碍事,但是修饰变量的时候记得加上,而且变量名要大写。

(5)总结

1、 final的理解:最终的

2、final可以用来修饰的结构:类、方法、变量(成员变量、局部变量)

3、具体说明:

  • final修饰:表示此类不能被继承。
    比如:String、StringBuffer、StringBuilder类

  • final修饰方法:表示此方法不能被重写
    比如:Object类中的getClass()

  • final修饰变量:既可以修饰成员变量,也可以修饰局部变量。
    此时的"变量"其实就变成了"常量",意味着一旦赋值,就不可更改。

    • final修饰成员变量: 有哪些位置可以给成员变量赋值?
      > 显式赋值
      > 代码块中赋值
      > 构造器中赋值

    • final修饰局部变量:一旦赋值就不能修改
      > 方法内声明的局部变量:在调用局部变量前,一定需要赋值。而且一旦赋值,就不可更改
      > 方法的形参:在调用此方法时,给形参进行赋值。而且一旦赋值,就不可更改

4、 finalstatic搭配:修饰成员变量时,此成员变量称为:全局常量。
比如:Math的PI

三、 笔试题

(1)题1

排错

public class Something {
    public int addOne(final int x) {
        //return ++x;	//不可以
        return x + 1;	//可以,x值没有变
    }
}

(2)题2

排错

public class Something {
    public static void main(String[] args) {
        Other o = new Other();
        new Something().addOne(o);
    }
    public void addOne(final Other o) {
        // o = new Other();
        o.i++;	//让i++可以,因为i是变量,o不能变
    }
}
class Other {
    public int i;
}

局部变量o指向一个Other对象,Other对象里面有一个i,i没有用final修饰,表示它是一个变量。

将o加了一个final,意味着它的地址不能变了,而o指向的对象的属性可以变化。

如下:
image.png

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

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

相关文章

信号功率放大器的工作原理和特点是什么

信号功率放大器是一种电子设备,用于将输入信号的功率进行放大,以达到所需的输出功率水平。它在各个领域中都有广泛的应用,包括音频放大器、射频放大器、激光功率放大器等。下面将详细介绍信号功率放大器的工作原理和特点。 工作原理&#xff…

基于 Modbus 的工业数据采集、控制(part 3)

Modbus 设备(利用 slave 模拟) Modbus 采集程序 client.c #include "client.h"modbus_t *ctx; key_t key_shm, key_msg; int shmid, msgid; struct shm *shm0; struct msgbuf msg0;void *collector(void *arg) {struct shm *p = (struct shm *)arg;while (1){sle…

ArgoWorkflow教程(一)---DevOps 另一选择?云原生 CICD: ArgoWorkflow 初体验

来自:探索云原生 https://www.lixueduan.com 原文:https://www.lixueduan.com/posts/devops/argo-workflow/01-deploy-argo-workflows/ 本文主要记录了如何在 k8s 上快速部署云原生的工作流引擎 ArgoWorkflow。 ArgoWorkflow 是什么 Argo Workflows 是…

深入理解路由协议:从概念到实践

路由技术是Internet得以持续运转的关键所在,路由是极其有趣而又复杂的课题,永远的话题。 SO:这是一个解析路由协议的基础文章。 目录 前言路由的概念路由协议的分类数据包在网络中的路由过程理解路由表的结构路由器关键功能解析 前言 在互联…

文件差分服务设计

需求 OTA(Over-The-Air)升级是一种至关重要的技术,用于更新嵌入式设备的固件或软件,以确保设备具备最新功能和修复漏洞。在OTA升级过程中,使用差异算法工具(如bsdiff、hdiffpatch和xdelta3)能够…

eNSP-直连通信实验

实验拓扑: 实验需求: 1. 按照图中的设备名称,配置各设备名称 2. 按照图中的IP地址规划,配置IP地址 3. 测试R1与R2是否能ping通 4. 测试R2与R3是否能ping通 5. 测试R1与R3是否能ping通 实验步骤: 1. 加入设备&…

2023亚太杯数学建模C题思路 - 我国新能源电动汽车的发展趋势

1 赛题 问题C 我国新能源电动汽车的发展趋势 新能源汽车是指以先进技术原理、新技术、新结构的非常规汽车燃料为动力来源( 非常规汽车燃料指汽油、柴油以外的燃料),将先进技术进行汽车动力控制和驱动相结 合的汽车。新能源汽车主要包括四种类型&#x…

应用带通滤波器进行划痕检测

案例要求: 图为HALCON中的例图“surface_scratch”,请提取出图中的划痕。 案例分析: 图中明亮程度不一,划痕颜色较淡,因此不能用灰度BLOB分析的方法提取出目标区域。因此,先构造一个带通滤波器&#xff0…

Linux编程 文件操作 creat open

文件描述符 文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。 启动一个进程之后,…

3.OpenFeign的使用

OpenFeign 文章目录 OpenFeign一. 什么是OpenFeign二. OpenFeign基础使用1.添加依赖2.配置Nacos配置信息3.在项目中开启OpenFeign4.编写OpenFeign调用代码5.调用OpenFeign接口 三. OpenFeign内置的超时重试机制1.配置超时重试2.覆盖Retryer对象 四.自定义超时重试机制1.自定义超…

vue3-生命周期

​🌈个人主页:前端青山 🔥系列专栏:Vue篇 🔖人终将被年少不可得之物困其一生 依旧青山,本期给大家带来vue篇专栏内容:vue3-生命周期 目录 vue3生命周期 vue3生命周期钩子 1.1 onMounted() 1.2 onUpdated() 1.3 onU…

Airtest结合Poco对控件实施精准截图,学起来!

1.前言 最近在Q群内发现有个小伙伴提出了一个很有趣的脚本需求,想要实现“通过选择器获取到了控件,然后截图这个控件范围”,根据我们的Airtest的局部截图接口以及poco控件的属性查询接口是可以很快实现的~ 2.接口查找 首先我们需要知道我们…

什么软件可以做报表?

报表在现代企业和组织中扮演着重要角色。它们是数据汇总、分析和展示的重要工具,为管理层和决策者提供洞察和指导。但是,报表的制作并非易事。使用Excel或手写代码开发报表可能会带来一系列痛点,而现代化的解决方案——比如VeryReport报表软件…

分布式锁之传统锁回顾(一)

1. 传统锁回顾 1.1. 从减库存聊起 多线程并发安全问题最典型的代表就是超卖现象 库存在并发量较大情况下很容易发生超卖现象,一旦发生超卖现象,就会出现多成交了订单而发不了货的情况。 场景: 商品S库存余量为5时,用户A和B同…

智能导视电子指路牌是什么?

SVIP-3800系列智能电子指路牌也称智慧指路灯杆,智能指路牌,导航立柱,多功能指示牌,多功能路标,智能指路机器人,智能导视指路牌,问路导航机器人,智能路牌,叁仟智慧路牌、智…

电商数据采集|电商API接口接入|从京东平台获取商品SKU 主图 价格 详情数据

在进行API开发过程中,数据异常常常令人头痛。我们的API开车软件经过精心设计和测试,能够准确识别并及时处理各类数据异常。拥有稳定的运行环境,保障了您的开发进程不受干扰,让您的工作更加顺畅高效。 京东获得JD商品详情 API 返…

AI助力钢铁产业数字化,python基于YOLOv5开发构建钢铁产业产品智能自动化检测识别系统

AI为工业产业智能化数字化赋能早已不是什么新鲜事,越来越多的行业和领域开始更大范围去拥抱AI,享受科技带来的变革力量,在我们之前的文章中也有很多相关领域项目的实践经历,本文的核心目标就是想要基于钢铁领域产品数据来开发构建…

VirtualBox下win主机如何访问linux虚拟机文件夹

目录 ​编辑 方法1:通过VirtualBox自带的共享文件夹(Win->linux) 方法2:通过Samba方法本地网络访问(Linux->win) 我使用的VirtualBox版本为7.0.4,主机是Window系统,虚拟机是Linux系统 方法1:通过Vir…

易点易动设备管理系统提升设备能耗管理和设备状态监控效率

如今,能源效率和设备状态监控对于企业来说变得越发重要。传统的设备管理方式往往存在能耗浪费和难以实时监控设备状态的问题。为了解决这些问题,易点易动设备管理系统应运而生。本文将介绍易点易动设备管理系统的功能和优势,以及如何通过它提…

深度学习之六(自编码器--Autoencoder)

概念 自编码器(Autoencoder)是一种神经网络架构,用于无监督学习和数据的降维表示。它由两部分组成:编码器(Encoder)和解码器(Decoder)。 结构: 编码器(Encoder): 接收输入数据并将其压缩为潜在表示(latent representation),通常比输入数据的维度要低。编码器的…