java类成员/final/static都涉及到了2023025

news2024/12/26 11:37:28

类成员:
在Java类里只能包含成员变量、方法、构造器、初始化块、内部类(包括接口、枚举)这5种成员,目前已经介绍了前面4种,其中static可以修饰成员变量、方法、初始化块、内部类(包括接口,枚举,以static修饰的成员就是类成员。类成员属于整个类,而不属于单个对象。
类变量属于整个类,当系统第一次准备使用该类时,系统会为该类变量分配内存空间,类变量开始生效,直到该类被卸载,该类的类变量所占有的内存才被系统的垃圾回收机制回收。类变量生存范围几乎等同于该类的生存范围。当类初始化完成后,类变量也被初始化完成。
类变量既可通过类来访问,也可通过类的对象来访问。但通过类的对象来访问类变量时,实际上并不是访问该对象所拥有的变量,因 为当系统创建该类的对象时,系统不会再为类变量分配内存,也不会再次对类变量进行初始化,也就是说,对象根本不拥有对应类的类变量。通过对象访问类变量只是一种假象,通过对象访问的依然是该类的类变量,可以这样理解:当通过对象来访问类变量时,系统会在底层转换为通过该类来访问类变量。
提示:
很多语言都不允许通过对象访问类变量,对象只能访问实例变量;类变量必须通过类来访问。
由于对象实际上并不持有类变量,类变量是由该类持有的,同一个类的所有对象访问类变量时,实际上访问的都是该类所持有的变量。因此,从程序运行表面来看,即可看到同一类的所有实例的类变量共享同一块内存区。类方法也是类成员的一种,类方法也是属于类的,通常直接使用类作为调用者来调用类方法,但也可以使用对象来调用类方法。与类变量类似,即使使用对象来调用类方法,其效果也与采用类来调用类方法完全一样。
当使用实例来访问类成员时,实际上依然是委托给该类来访问类成员,因此即使某个实例为null,它也可以访问它所属类的类成员。
空指针怎么来的?
如果一个null对象访问实例成员(包括实例变量和实例方法),将会引发NullPointerException异常,因为null表明该实例根本不存在,既然实例不存在,那么它的实例变量和实例方法自然也不存在。
类初始化块(静态初始化块)也是类成员的一种,类初始化块用于执行类初始化动作,在类的初始化阶段,系统会调用该类的类初始化块来对类进行初始化。一旦该类初始化结束后,类初始化块将永远不会获得执行的机会。
对static关键字而言,有一条非常重要的规则:类成员(包括成 员变量、方法、初始化块、内部类和内部枚举)不能访问实例成员 (包括成员变量、方法、初始化块、内部类和内部枚举)。因为类成员是属于类的,类成员的作用域比实例成员的作用域更大,完全可能出现类成员已经初始化完成,但实例成员还不曾初始化的情况,如果允许类成员访问实例成员将会引起大量错误。

static的一个重要应用:单例类,单例类又是什么呢?
单例(Singleton)类
大部分时候都把类的构造器定义成public访问权限,允许任何类自由创建该类的对象。但在某些时候,允许其他类自由创建该类的对象没有任何意义,还可能造成系统性能下降(因为频繁地创建对象、 回收对象带来的系统开销问题)。
例如,系统可能只有一个窗口管理器、一个假脱机打印设备或一个数据库引擎访问点,此时如果在系统中为这些类创建多个对象就没有太大的实际意义。
如果一个类始终只能创建一个实例,则这个类被称为单例类。
总之,在一些特殊场景下,要求不允许自由创建该类的对象,而只允许为该类创建一个对象。为了避免其他类自由创建该类的实例, 应该把该类的构造器使用private修饰,从而把该类的所有构造器隐藏起来。
根据良好封装的原则:一旦把该类的构造器隐藏起来,就需要提供一个public方法作为该类的访问点,用于创建该类的对象,且该方法必须使用static修饰(因为调用该方法之前还不存在对象,因此调用该方法的不可能是对象,只能是类)。
除此之外,该类还必须缓存已经创建的对象,否则该类无法知道是否曾经创建过对象,也就无法保证只创建一个对象。为此该类需要使用一个成员变量来保存曾经创建的对象,因为该成员变量需要被上面的静态方法访问,故该成员变量必须使用static修饰。
在这里插入图片描述
final修饰符:
final关键字可用于修饰类、变量和方法,用于表示它修饰的类、方法和变量不可改变。
final修饰变量时,表示该变量一旦获得了初始值就不可被改变,
final既可以修饰成员变量(包括类变量和实例变量),也可以修饰局部变量、形参。
有的书上介绍说final修饰的变量不能被赋值,这种说法是错误的!严格的说法是,final修饰的变量不可被改变,一旦获得了初始值,该final变量的值就不能被重新赋值。由于final变量获得初始值之后不能被重新赋值,因此final修饰成员变量和修饰局部变量时有一定的不同。
成员变量是随类初始化或对象初始化而初始化的。当类初始化时,系统会为该类的类变量分配内存,并分配默认值;当创建对象时,系统会为该对象的实例变量分配内存,并分配默认值。也就是说,当执行静态初始化块时可以对类变量赋初始值;当执行普通初始化块、构造器时可对实例变量赋初始值。因此成员变量的初始值可以在定义该变量时指定默认值,也可以在初始化块、构造器中指定初始值。
对于final修饰的成员变量而言,一旦有了初始值,就不能被重新赋值,如果既没有在定义成员变量时指定初始值,也没有在初始化块、构造器中为成员变量指定初始值,那么这些成员变量的值将一直是系统默认分配的0、‘\u0000’、false或null,这些成员变量也就完全失去了存在的意义。因此Java语法规定:final修饰的成员变量必须由程序员显式地指定初始值,归纳起来,final修饰的类变量、实例变量能指定初始值的地方如下。
1.类变量:必须在静态初始化块中指定初始值或声明该类变量时指定初始值,而且只能在两个地方的其中之一指定。
2.实例变量:必须在非静态初始化块、声明该实例变量或构造器中指定初始值,而且只能在三个地方的其中之一指定。但需要注意的是,如果普通初始化块已经为某个实例变量指定了初始值,则不能再在构造器中为该实例变量指定初始值;

final修饰局部变量又回怎样呢?
系统不会对局部变量进行初始化,局部变量必须由程序员显式初始化。因此使用final修饰局部变量时,既可以在定义时指定默认值,也可以不指定默认值。
如果final修饰的局部变量在定义时没有指定默认值,则可以在后面代码中对该final变量赋初始值,但只能一次,不能重复赋值;如果final修饰的局部变量在定义时已经指定默认值,则后面代码中不能再对该变量赋值。下面程序示范了final修饰局部变量、形参的情形。
在这里插入图片描述

final修饰基本类型变量和引用类型变量的区别
当使用final修饰基本类型变量时,不能对基本类型变量重新赋值,因此基本类型变量不能被改变。但对于引用类型变量而言,它保存的仅仅是一个引用,final只保证这个引用类型变量所引用的地址不会改变,即一直引用同一个对象,但这个对象完全可以发生改变。

引申出宏变量:
Java会使用常量池来管理曾经用过的字符串直接量,例如执行var a=“java”;语句之后,常量池中就会缓存一个字符串"java";如果程序再次执行var b=“java”;,系统将会让b直接指向常量池中的"java"字符串,因此a==b将会返回true。
还有一种场景:
在这里插入图片描述
final修饰方法是什么样呢?
final修饰的方法不可被重写,如果出于某些原因,不希望子类重写父类的某个方法,则可以使用final修饰该方法。Java提供的Object类里就有一个final方法:getClass(),因为
Java不希望任何类重写这个方法,所以使用final把这个方法密封起来。但对于该类提供的toString()和equals()方法,都允许子类重写,因此没有使用final修饰它们。final修饰的方法仅仅是不能被重写,是可以重载的。但是也知道,重载一半时在一个类里做的,相当于两个不同的方法。
注意事项:private修饰的方法是可以在子类中加final的,private final sss(){},为啥呢?
对于一个private修饰的方法,它仅在当前类中可见,其子类无法访问该方法,所以子类无法重写该方法—如果子类中定义一个与父类private方法有相同方法名、相同形参列表、相同返回值类型的方法, 也不是方法重写,只是重新定义了一个新方法。也就是说子类中的同名方法和父类中的没有毛线关系,那在子类中使用final修饰一个private访问权限的方法一点毛病没有,依然可以在其子类中定义与该方法具有相同方法名、相同形参列表、相同返回值类型的方法。

更进一步,final修饰类怎么办?
final修饰的类不可以有子类,例如java.lang.Math类就是一个final类,它不可以有子类。
当子类继承父类时,将可以访问到父类内部数据,并可通过重写父类方法来改变父类方法的实现细节,这可能导致一些不安全的因素。为了保证某个类不可被继承,则可以使用final修饰这个类。
那么final修饰就是不可变类了???不完全,还有其他要求
不可变(immutable)类的意思是创建该类的实例后,该实例的实例变量是不可改变的。Java提供的8个包装类和java.lang.String类都是不可变类,当创建它们的实例后,其实例的实例变量不可改变。
如果需要创建自定义的不可变类,可遵守如下规则。
1.使用private和final修饰符来修饰该类的成员变量。且的关系?
2.提供带参数的构造器(或返回该实例的类方法),用于根据传入参数来初始化类里的成员变量。
3.仅为该类的成员变量提供getter方法,不要为该类的成员变量提供setter方法,因为普通方法无法修改final修饰的成员变量。
4.如果有必要,重写Object类的hashCode()和equals()方法。equals()方法根据关键成员变量来作为两个对象是否相等的标准,除此之外,还应该保证两个用equals()方法判断为相等的对象的hashCode()也相等。
例如,java.lang.String这个类就做得很好,它就是根据String对象里的字符序列来作为相等的标准,其hashCode()方法也是根据字符序列计算得到的。

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

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

相关文章

显示器的相关知识

目录 显示器的作用 显示器的尺寸 人眼的可视角度 显示器的分辨率 显示器的刷新率 显示器的灰阶响应时间 显示器的色域 显示器的色深 显示器的色准 显示器的HDR参数 显示器的面板 画面撕裂 前言 导致画面撕裂的原因 防画面撕裂技术 视频的码率 显示器的作用 把…

Golang 多模块开发

Golang 多模块开发 今天学习下Golang中多模块的基础知识,学习多模块的运行原理,使用多模块的方式,可以让开发者的代码在其他多个模块中构建、运行。提高代码的复用,从而提高开发效率。 在今天的学习中,将在工作工作空…

bfs入门教程(广度优先搜索)(含图解)

源自《啊哈算法》 目录 bfs正文 题目 思路 完整代码1 完整代码2 再解炸弹人 题目 思路 完整代码1 完整代码2 总结 bfs正文 第四章--深度优先搜索中,我们用dfs找到了寻找小哈的最短路径 接下来,我们要用bfs(Breadth First Sear…

Zookeeper的本地安装部署和分布式安装部署

文章目录一. 本地模式安装部署1)安装前准备2)配置修改3)操作Zookeeper1.2 配置参数解读二. 分布式安装部署1)集群规划2)解压安装3)配置服务器编号4)配置zoo.cfg文件5)集群操作客户端…

Leetcode.126 单词接龙 II

题目链接 Leetcode.126 单词接龙 II 题目描述 按字典 wordList完成从单词 beginWord到单词 endWord转化,一个表示此过程的 转换序列 是形式上像 beginWord -> s1 -> s2 -> ... -> sk这样的单词序列,并满足: 每对相邻的单词之间…

《高效能团队模式》读书笔记2

如果我们将团队类型的数量缩减为四类基本团队拓扑,这个问题就迎刃而解了。 流动式团队 赋能团队 复杂子系统团队 平台团队只要使用得当,这四类团队拓扑能够满足构建和运行现代软件系统的需要。结合有效的软件边界(第6章)和团队交互…

Java注解,元注解,自定义注解的使用

Java注解,元注解,自定义注解的使用Java注解基本的注解1.Override2.Deprecated3.SuppressWarnings4.SafeVarargs5.FunctionalInterfaceJava提供的元注解1.Retention2.Target3.Documented4.Inherited自定义注解自定义注解的使用Java注解 从JDK5开始,Java增…

从旺店通·企业奇门到用友U8通过接口集成数据

接入系统:旺店通企业奇门慧策(原旺店通)是一家技术驱动型智能零售服务商,基于云计算PaaS、SaaS模式,以一体化智能零售解决方案,帮助零售企业数字化智能化升级,实现企业规模化发展。对接系统&…

本地数仓项目(四)—— 即席查询

1 背景 本文描述本地数仓项目即席查询相关内容,主要涉及即席查询工具包括Presto、Druid、Kylin。 本文基于文章《本地数据仓库项目(一) —— 本地数仓搭建详细流程》 和《本地数仓项目(二)——搭建系统业务数仓详细流程》以及《本地数仓项目(三)—— 数…

金蝶云星辰和旺店通企业版奇门单据接口集成

金蝶云星辰V1和旺店通企业奇门单据接口集成对接源平台:旺店通企业奇门慧策(原旺店通)是一家技术驱动型智能零售服务商,基于云计算PaaS、SaaS模式,以一体化智能零售解决方案,帮助零售企业数字化智能化升级,实…

图的基本概念以及表示方法(链式前向星重点理解,简单易懂版)

图表示一个集合中元素之间存在的多对多关系的一种数据结构。 图的一些定义 : 1.图由顶点和连接顶点的边构成,即G ( V , E ) ,其中V为顶点集合,E为边的集合。2.边表示两个顶点之间存在某种关系,边表示为(…

Elasticsearch7.8.0版本高级查询—— 单字段排序文档

目录一、初始化文档数据二、单字段排序文档2.1、概述2.2、示例一、初始化文档数据 在 Postman 中,向 ES 服务器发 POST 请求 :http://localhost:9200/user/_doc/1,请求体内容为: { "name":"zhangsan", "…

可笑 在网页上复制点东西 还需要money?进来看~

前言 哈喽 大家好! 我是木易巷,我回来啦!!! 现在好多平台都变成了不开会员不能复制这样的情况。士可杀不可辱!作为一个优秀的复制粘贴工程师,在网页上复制点东西,还需要我掏钱&#…

【Springboot】idea中配置文件不生效、自动提示功能消失、小绿标不出现现象

怎么解决idea中配置文件不生效、自动提示功能消失、小绿标不出现现象先要明确一个核心,就是自动提示功能不是SpringBoot技术给我们提供的,是我们在Idea工具下编程,这个编程工具给我们提供的。明白了这一点后,再来说为什么会出现这…

07.C语言文件操作

1. 使用文件的原因我们前面学习结构体时,写了通讯录的程序,当通讯录运行起来的时候,可以给通讯录中增加、删除数据,此时数据是存放在内存中,当程序退出的时候,通讯录中的数据自然就不存在了,等下…

盒模型 盒子的组成部分 1. 内容 content 2. 填充 (内边距) padding 3. 边框 border 4. 外边距 margin

目录盒模型盒子的组成部分1. 内容 content2. 填充 (内边距) padding3. 边框 border4. 外边距 margin盒模型 box:盒子,每个元素在页面中都会生成一个矩形区域(盒子) 盒子类型: 行盒,display等于inline的元…

使用Seq2Seq实现中英文翻译

介绍 Deep NLP 自然语言处理NLP是计算机科学、人工智能和语言学交叉领域的分支科学,主要让计算机处理和理解自然语言,如机器翻译、问答系统等。但因其在学习和使用语言的复杂性,通常认为NLP是困难的,近几年,随着深度…

MedCalc:生物医学研究的统计软件 Crack

MedCalc:生物医学研究的统计软件 MedCalc是用于生物医学研究的统计软件包,统计数据包括 220 多个统计测试、程序和图表,ROC曲线分析、方法比较和质量控制工具。 简单易学,快速可靠 MedCalc 包括 220 多种统计测试、程序和图表 RO…

springboot+vue整合JustAuth实现第三方登录

前后端分离版实现第三方登录&#xff1a;GITEE为例 1&#xff1a;首先maven安装依赖&#xff1a; <!-- oauth工具类 --><dependency><groupId>com.xkcoding.justauth</groupId><artifactId>justauth-spring-boot-starter</artifactId><…

学习wifi操作模块simplewifi的基本用法

之前学习Python的过程中学过基于pywifi模块操作wifi连接的用法&#xff0c;在dotnet中&#xff0c;SimpleWifi也支持类似的功能。SimpleWifi是C#语言编写的在Windows系统中管理wifi连接的库&#xff0c;它抽象并封装了Managed Wifi API中的wifi操作相关函数&#xff0c;更易于使…