当前位置: 首页 > news >正文

【Java】成员变量和局部变量的区别

变量有作用范围的概念,并且根据作用范围的不同,变量还可以分为成员变量、局部变量等内容。

一、概念

我们知道,在 Java 中,变量是程序里最基本的存储单元,它由变量名、变量类型、作用域组成。从本质上来说,变量其实就是内存里的一小块存储区域,该区域只能存储声明变量时指定类型的数据。我们创建使用每个变量前,必须先声明,在内存中申请空间,然后对其进行初始化赋值,接着就可以通过变量名来访问和使用这块内存区域了

进一步解释下,变量其实就是一个可以存储特定类型数据的容器。这个容器在内存中有自己的地址,为了方便的找到这个地址,我们可以给每个地址给个“名字”,这就是“变量名”。每个变量的数据类型都是固定不变的,但变量中对应数据的具体内容,却是可以改变的,所以“变量”指的就是内容可以改变的量。

二、命名规范

变量的命名需要遵循一定的规范,基本的规则和规范如下:

  • Java 标识符由 字母(含英、中、日、俄等)、数字、下划线“_”和美元符号$组成,如 age、G7、_value、¥salary;
  • 不能以数字开头,如 123abc;
  • 严格区分大小写,如 class 与 Class 是不同的;
  • 长度无限制(一般不要超过15个字符);
  • 不能是 Java 中的保留字和关键字。

Java 的变量名也是一种标识符,所以必须遵循以上这些规则!另外还有一些命名规范需要我们尽量遵守,比如:

  • 变量名尽量要做到见名知意。在实际开发时尽量不要写a、b、c这种名称;
  • 变量名的首字母要小写。如果名称由多个单词组成,第一个单词的首字母应小写,剩下的单词首字母应大写(驼峰式命名法),例如 xxxYyyZzz、numCounter。

三、作用范围

其实,除了以上的这些规则之外,我们在定义变量时还要考虑它的作用范围,或者说是作用域。

变量的作用范围,或者用作用域,是指一个变量的有效范围。有的变量在整个类中都是有效的,也有的变量只在方法内部有效,超过这个范围就无效了。如果我们在超出了作用域的地方引用这些变量,编译器就会报错。这就好比,不同的人有不同的权力,有的人权力比较大,可以在全世界发号施令。有的人权力比较小,只能在自己家里发号施令,这就是自己的“作用范围”或者“作用域”。

我们在定义变量时,要遵循作用域最小化的原则,尽量将变量定义在尽可能小的范围内,并且不要重复使用变量名

四、变量分类

在 Java 中,我们可以根据变量的作用范围,将 Java 的变量分为两大类:

  • 局部变量:局部变量只在定义它的方法或代码块内部有效,不能在其他的方法或代码块中使用。也就是说,局部变量只在一个方法或代码块的一对 { } 之间有效。局部变量定义的范围包括形参、方法内部、代码块内部。
  • 成员变量:成员变量在整个类内部都有效,可以在当前类的任何方法中使用。根据是否带有 static 关键字,成员变量又分为静态变量(类变量)、实例变量(对象变量)

五、局部变量

1、概念

局部变量是在定义形参、方法或代码块内部的变量,该变量只在当前方法、代码块中有效。

2、特点

局部变量具有如下特点:

  • 局部变量声明在方法、构造方法或者代码块、形参中;
  • 局部变量在方法、构造方法、或者语句块被执行时创建,当他们执行完成后,局部变量就会被销毁;
  • 访问修饰符不能添加在局部变量上;
  • 局部变量只在声明它的方法、构造方法或者代码块、形参中可见;
  • 局部变量是在栈上分配内存的;
  • 局部变量没有默认值,所以局部变量被声明后,必须经过初始化,才可以使用。

3、案例

在下面的案例中,给大家定义了几个局部变量供大家参考。

public class Demo01 {// args 也是一种局部变量,在 main() {} 方法的 {} 范围内有效public static void main(String[] args) {// 局部变量,在 main() {} 方法的 {} 范围内有效int a = 10;System.out.println("a=" + a);}public void showAge() {// i 也是一种局部变量,只在 for() {} 这对 {} 范围内有效for (int i = 0; i < 100; i++) {System.out.println("age=" + age);}}}

六、成员变量

1、概念

所谓的成员变量,是指在类中(不是方法或其它代码块)直接定义的变量。根据是否带有 static 关键字,成员变量又分为静态变量(类变量)、实例变量(对象变量)。成员变量在整个类的内部都有效,可以在当前类的任何方法中使用。另外,如果成员变量不是被 private 修饰的,还可以在其他的类中引用。

2、实例变量

实例变量也被称为对象变量,是指在类中定义的非 static 变量。实例变量具有如下特点:

  • 实例变量声明在一个类中,但在方法、构造方法和语句块的外面;
  • 当一个对象被实例化之后,每个实例变量的值也就跟着确定了;
  • 实例变量在对象创建时创建,在对象被销毁时销毁;
  • 实例变量对于类中的方法、构造方法或者语句块都是可见的。一般情况下我们应该把实例变量设为私有,通过访问修饰符可以使实例变量对子类也可见;
  • 实例变量具有默认值。数值型变量的默认值是0,布尔型变量的默认值是 false,引用类型变量的默认值是 null。变量的值可以在声明时指定,也可以在构造方法中指定。
  • 实例变量可以直接通过变量名访问。但在静态方法以及其它类中,应该使用完全限定名:ObjectReference.VariableName。

3、静态变量

静态变量又被称为类变量,是被 static 修饰的、直接定义在类中(方法之外)的变量,它具有如下特点:

  • 静态变量可以被 public、private、final 和 static 修饰;
  • 静态变量在方法外面定义,但可以在静态语句块中初始化,且初始化后不可被改变;
  • 静态变量与实例变量具有相似的可见性。但为了对类的使用者可见,大多数静态变量都声明为 public 类型;
  • 静态变量的默认值和实例变量相似;
  • 静态变量通过 ClassName.VariableName 的形式进行访问;
  • 静态变量存储在静态存储区;
  • 静态变量在第一次被访问时创建,在程序结束时销毁;
  • 无论在一个类中创建了多少个对象,一个类都只拥有类变量的一份拷贝;
  • 静态变量被声明为 public static final 类型时,变量名称一般建议使用大写字母。

4、权限修饰符

大家要注意,成员变量的作用域,是可以通过权限修饰符来进行修改的。也就是说,我们可以给一个成员变量不同的修饰符,赋予该变量不同的权限。比如,我么可以给一个人身上赋予不同的“角色标签”,就可以改变这个人的“权力大小”。在 Java 中,有如下 4 种权限修饰符:

修饰符类内部同一个包不同包的其它子类同一个工程
private可以(继承是特例)
默认可以可以
protected可以可以可以
public可以可以可以可以

private 私有的修饰符:可以修饰成员变量、成员方法、构造方法,但不能修饰类(内部类除外)。被 private 修饰的成员只能在被修饰的本类中访问,在其它类中不能调用。一般被 private 修饰的成员变量,是通过公开的 set 和 get 方法向外界提供访问方式。

default 默认的修饰符:不用写任何关键字,它可以修饰类、成员变量、成员方法、构造方法。变量被默认权限修饰后,只能被本类以及同一个包下的其它类访问。

protected 受保护的修饰符:可以修饰成员变量、成员方法、构造方法,但不能修饰类(内部类除外)。成员变量被 protected 修饰后,可以在同一类内部,和同一包中的其它类访问。如果不同包中的类想要访问被 protected 修饰的成员,这个类必须是其子类。

public 公开的修饰符:是权限最大的修饰符,可以修饰类、成员变量、成员方法、构造方法。成员变量被 public 修饰后,可以在任何一个类中任意使用,不管是否是同一个包。

5、案例

在下面的案例中,定义了 2 个成员变量供大家参考:

public class Demo01 {// 实例变量、对象变量,在当前的 Demo01 类内部有效private int age = 18;// 静态变量、类变量,因为是 public 公开的,在当前 Demo01 类内部,及其他类中都可以使用public static String msg = "hello,你好";public static void main(String[] args) {// 注意:在 static 静态方法中不能引用非静态变量System.out.println("msg=" + msg);}}

七、总结

1、相同点:

  • 定义变量的格式相同:数据类型    变量名   =    变量值
  • 先声明,后使用;
  • 变量都有其对应的作用域。

2、不同点:

  • 在类中声明的位置不用

        成员变量(属性):直接定义在类的一对 { } 内,方法外面。又称之为字段(Field),不要称之为属性(错误)

        局部变量:除了成员变量,其它都是局部变量,具体存在于下面三个地方:方法内、方法的形参、代码块中(一对花括号)

  • 关于权限修饰符(作用域)的不同

        成员变量(属性):可以在声明属性时,指明其权限,使用权限修饰符。常用的权限修饰符:private、public、缺省、protected。目前,大家声明成员变量(属性)时,都是用缺省就可以了。

        局部变量:不可以使用权限修饰符。

  • 默认初始化值得情况

变量的初始化表示在内存中开辟存储空间,只有初始化之后,才能使用。

        成员变量(属性):类的属性,根据其类型,都有默认初始化值。

        局部变量:没有默认初始化值。意味着,我们在调用局部变量之前,一定要手动显式赋值。特别的,形参在调用时,我们赋值即可。

  • 变量的生命周期

变量的生命周期,表示变量在内存能存活多久。

        成员变量(属性):加载到堆空间中(非 static),随着对象的销毁而销毁

        局部变量:加载到栈空间中,随着所定义方法的调用结束而销毁

局部变量存储在方法中,每次调用方法都会在栈空间开辟一块内存空间 -- 栈帧,方法调用结束,栈帧就被销毁了,内存中的存储的变量数据也销毁了。

八、参考文档

Java中局部变量和成员变量的区别详解

相关文章:

  • PyTorch自动微分机制的详细介绍
  • Qt Excel读写 - QXlsx的安装配置以及测试
  • Android 中的动态应用程序图标
  • 蓝桥杯练习题-图书ISBN号码
  • 低代码与人工智能:实现智能化办公的利器
  • 糊涂工具包使用 记录
  • 空间域:空间组学的耶路撒冷
  • 网络安全知识和华为防火墙
  • 手机壳也能散热了?
  • 使用 create-react-app 创建 react 应用
  • 关机恶搞小程序
  • input框不能输入
  • 代码随想录算法训练营第35天 | 860.柠檬水找零 + 406.根据身高重建队列 + 452.用最少数量的箭引爆气球
  • [GN] 设计模式——面向对象设计原则概述
  • 【游戏服务器部署】幻兽帕鲁服务器一键部署保姆级教程,游戏私服还是自己搭建的香
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • 5分钟即可掌握的前端高效利器:JavaScript 策略模式
  • angular学习第一篇-----环境搭建
  • javascript数组去重/查找/插入/删除
  • Js基础知识(四) - js运行原理与机制
  • PHP 的 SAPI 是个什么东西
  • Promise面试题,控制异步流程
  • React 快速上手 - 07 前端路由 react-router
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 初探 Vue 生命周期和钩子函数
  • 离散点最小(凸)包围边界查找
  • 山寨一个 Promise
  • 实现菜单下拉伸展折叠效果demo
  • 问题之ssh中Host key verification failed的解决
  • 用Visual Studio开发以太坊智能合约
  • 字符串匹配基础上
  • ​ 无限可能性的探索:Amazon Lightsail轻量应用服务器引领数字化时代创新发展
  • #define
  • (二十五)admin-boot项目之集成消息队列Rabbitmq
  • (转)EXC_BREAKPOINT僵尸错误
  • .MyFile@waifu.club.wis.mkp勒索病毒数据怎么处理|数据解密恢复
  • .Net core 6.0 升8.0
  • .NET6 命令行启动及发布单个Exe文件
  • .NET牛人应该知道些什么(2):中级.NET开发人员
  • .NET是什么
  • .考试倒计时43天!来提分啦!
  • @31省区市高考时间表来了,祝考试成功
  • [ Linux Audio 篇 ] 音频开发入门基础知识
  • [AUTOSAR][诊断管理][ECU][$37] 请求退出传输。终止数据传输的(上传/下载)
  • [BUUCTF 2018]Online Tool
  • [BZOJ] 2006: [NOI2010]超级钢琴
  • [C#]C# winform部署yolov8目标检测的openvino模型
  • [C语言]——柔性数组
  • [DAU-FI Net开源 | Dual Attention UNet+特征融合+Sobel和Canny等算子解决语义分割痛点]
  • [Editor]Unity Editor类常用方法
  • [Java] 模拟Jdk 以及 CGLib 代理原理
  • [linux] shell中的()和{}
  • [MZ test.16]P1 评测
  • [NHibernate]条件查询Criteria Query
  • [node] Node.js的文件系统