[JAVA基础] 成员变量和局部变量(一看就懂的总结归纳篇)

在这里插入图片描述

JVM中的主要内存空间


在这里插入图片描述

三大变量内存分配情况


在这里插入图片描述

三区介绍


栈区

存放各种方法(静态方法、实例方法、构造方法等)

ps:局部变量就在这些方法体中;

堆区

存放new出来的对象(实例);

方法区

存放各个类,且静态变量在此初始化;


基本介绍

==============================================================

成员变量是在 类 中定义的变量

局部变量是在 方法 中定义的变量

成员变量


成员变量分为静态变量(类变量)实例变量

静态变量有static修饰,它从该类的准备阶段就存在了,直到系统销毁这个类,静态变量的作用域与这个类的生存范围相同

实例变量没有static修饰,它从该类的实例被创建时就存在,直到系统销毁这个实例,实例变量的作用域与对应实例的生存范围相同

静态变量访问方法:通过类名访问,不需要创建实例;

类.静态变量

实例变量访问方法:通过实例访问,需要先new一个实例

实例.实例变量

其实这里主要注意的还是静态变量,主要内容可以看看我的这篇文章:Java中的static———静态变量

这里主要说一下成员变量初始化时在内存中运行机制;

先看一个代码:

public class MemoryShow {

public static void main(String[] args) {

Person p1 = new Person();

Person p2 = new Person();

Person.name = “李四”;

System.out.println(“姓名:” + Person.name);

System.out.println(“p1年龄:” + p1.age);

System.out.println(“p2年龄:” + p2.age);

}

}

class Person {

//静态变量

static String name = “张三”;

//实例变量

int age;

}

简单分析一下,当程序第一次执行Person类时,系统先加载这个类,并初始化这个类,在类的准备阶段,系统就为该类的类变量分配内存空间,并指定默认初始值(静态变量name也是在这个阶段完成了初始化);

然后接下来系统就在堆内存中为Person类分配了一块内存区,且为age默认赋值为0;然后生成了Person对象,并通过引用变量p1指向该对象;

当再次执行Person类时,已经不需要再为Person类初始化了,所以直接生成了Person对象,通过p2指向它;

局部变量


局部变量相对成员变量就没有那么复杂了

先分别介绍一下局部变量中的三种不同形式:

形参: 在定义方法签名时定义的变量,形参的作用域在整个方法内有效

方法局部变量:方法体中定义的变量,作用域从定义该变量的地方生效,到该方法结束时失效

代码块局部变量: 在代码块中定义的变量,作用域从定义该变量的地方生效,到该代码块结束时失效

和成员变量不同的一点是:局部变量除了形参外,都需要显式初始化,就是指定一个初始值,否则无法访问;

局部变量在内存中的运行机制:

因为局部变量需要显式初始化,所以系统不会对它进行初始化,即系统并没有给局部变量分配内存空间,只有它赋值后,系统才会分配内存将该值放入其中;

因为局部变量不属于任何对象或者类,所以它存放在栈内存中,且栈内存的变量不需要系统垃圾回收,因为它们会随着方法或者代码块运行结束而结束;所以局部变量只保存基本类型或者对象的引用(引用变量),所以局部变量占用内存比较小;

java语法允许局部变量和成员变量重名,但是如果在一个方法里,局部变量会覆盖成员变量

如果想要在该方法里访问成员变量,就需要通过**this引用(针对实例变量)或者类名(针对静态变量)**作为调用者来限定访问成员;

看一个代码就明白了:

public class RepeatTest {

// 静态变量(类变量)

static String name = “张三”;

// 实例变量

int age = 18;

public static void main(String[] args) {

// 局部变量 和静态变量name = "张三"重名

String name = “李四”;

// 因为静态变量name被这里的局部变量覆盖,所以输出为“李四”

System.out.println(“姓名:” + name);

// 这时候如果想要调用静态变量可以使用类来调用

//不能用this调用的原因是:main方法是静态方法

System.out.println(“姓名:” + RepeatTest.name);

// 调用test方法

new RepeatTest().test();

}

public void test() {

// 局部变量 和实例变量age = 18重名

int age = 666;

// 因为实例变量name被这里的局部变量覆盖,所以输出为“666”

System.out.println(“年龄:” + age);

// 这时候如果想要调用实例变量可以使用this调用

System.out.println(“年龄:” + this.age);

}

}

但是,从现在开始就要养成良好的编程习惯,在写代码时不要出现局部变量和成员变量重名的情况;

变量使用

==============================================================

说了这么多,可能你已经晕了,但是这些变量归根结底我们了解它们就是为了用它们,那什么时候用局部变量,什么时候用成员变量呢?

我们先看三个代码:

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

这份文档从构建一个键值数据库的关键架构入手,不仅带你建立起全局观,还帮你迅速抓住核心主线。除此之外,还会具体讲解数据结构、线程模型、网络框架、持久化、主从同步和切片集群等,帮你搞懂底层原理。相信这对于所有层次的Redis使用者都是一份非常完美的教程了。

image

整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~

你的支持,我的动力;祝各位前程似锦,offer不断!!!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
此之外,还会具体讲解数据结构、线程模型、网络框架、持久化、主从同步和切片集群等,帮你搞懂底层原理。相信这对于所有层次的Redis使用者都是一份非常完美的教程了。

[外链图片转存中…(img-f8wqKjR2-1713512073405)]

整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~

你的支持,我的动力;祝各位前程似锦,offer不断!!!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值