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

引言

成员变量和局部变量在每种编程语言中都有涉及,如果之前了解过其他语言的成员变量或者局部变量,那么在学习java中的成员变量和局部变量时可以看看有那些联系和不同,这一块的东西也不能说难,如果第一次接触可能会感觉有点乱,所以接下来我先把java中总结的成员变量和局部变量的部分内容先列出来,带着这些内容学起来会轻松很多!

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);}
}

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

变量使用

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

public class ScopeTest01 {//静态变量(类成员变量)//再次强调一下这里为什么定义静态变量而不是实例变量//因为main方法是静态方法,不需要对象只通过类调用,而实例变量必须有对象才能调用static int i;public static void main(String[] args) {for (i = 0; i < 5; ++i) {System.out.println("Hello World!!!");}}
}
public class ScopeTest02 {public static void main(String[] args) {//局部变量int i;for (i = 0; i < 5; ++i) {System.out.println("Hello World!!!");}}
}
public class ScopeTest03 {public static void main(String[] args) {// 代码块局部变量for (int i = 0; i < 5; ++i) {System.out.println("Hello World!!!");}}
}

这三个代码的运行结果都是一样的,而它们分别用了成员变量和局部变量,结果都一样,那我们就需要看看那种方法是最好的了;

首先,ScopeTest01 使用的是成员变量,我们都知道成员变量存在于堆内存中,且只有类销毁时或者实例销毁时它才销毁,这就将作用域扩大到类存在范围或者实例存在范围,作用域的扩大有两个坏处

  1. 增加了变量的生存时间,会导致更大的内存开销
  2. 扩大了变量的作用域,不利于提高程序的内聚性

同理可以对比ScopeTest02 和 ScopeTest03,最后可以总结出 ScopeTest03 最符合规范

所以定义变量的时候要尽可能的保证作用范围最小,这样可以很好的提高程序的性能,包括局部变量;

考虑使用成员变量有四种情况

  1. 如果定义的变量需要描述对象的信息,且每个对象都有可能不同,那么用成员变量中的实例变量
  2. 如果定义的变量所描述的信息这个类的所有对象都相同,那么类相关的信息就定义为成员变量中的静态变量
  3. 如果某个类中需要一个变量保存该类或者实例运行时的状态信息,该变量定义为成员变量;
  4. 如果某个信息需要在类的多个方法之间共享,则该信息使用成员变量

总结

成员变量和局部变量大概主要内容就是这些了,看完可能还是有点乱,一定要多看几遍,自己总结一下,这些东西是学习java的基础内容,这都搞不清的话,那么之后一会一个静态变量,一会一个局部变量都把你搞晕了;并且想要用java写出来好代码,就必须了解这些内容,这将会在你未来的开发中起到重要作用;

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

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

相关文章

【Java多线程】内存模型JMM—主内存与工作内存分析

文章目录JAVA内存模型JVM主内存与工作内存描述JVM内存间交互规则JVM先行发生原则内存交互基本操作的 3 个特性原子性(Atomicity)可见性(Visibility)有序性(Ordering)上述内存模型与Java多线程之间的问题JAVA内存模型 共享变量&#xff1a;如果一个变量在多个线程的工作内存中都…

SpringBoot配置MyBatis的sql执行超时时间(mysql)

当某些sql因为不知名原因堵塞时&#xff0c;为了不影响后台服务运行&#xff0c;想要给sql增加执行时间限制&#xff0c;超时后就抛异常&#xff0c;保证后台线程不会因为sql堵塞而堵塞。 方法一 yml全局配置&#xff1a;单数据源可以&#xff0c;多数据源时会失效 方法二 j…

HTTP协议中的302,303状态码

之前也只知道302,303是请求重定向,但是当被问到302,303的具体区别是什么的时候我有点迷,现在就为了加强记忆,来了解下具体情况: 302是http1.0的内容&#xff0c;303是http1.1的内容。301和302本来在规范中是不允许重定向时改变请求方法的&#xff08;将POST改为GET&#xff09…

Spring自带工具类(断言、ObjectUtils、FileCopyUtils、ResourceUtils、StreamUtils、ReflectionUtils、AopUtils、AopCont)

文章目录断言对象、数组、集合文件、资源、IO 流反射、AOP断言 断言是一个逻辑判断&#xff0c;用于检查不应该发生的情况Assert 关键字在 JDK1.4 中引入&#xff0c;可通过 JVM 参数-enableassertions开启SpringBoot 中提供了 Assert 断言工具类&#xff0c;通常用于数据合法…

Arrays.asList踩坑——引发的Exception in thread “main“ java.lang.UnsupportedOperationException

Exception in thread “main” java.lang.UnsupportedOperationException 如果你尝试修改Arrays.asList方法生产的List&#xff0c;那么就会报这个错误 public static void main(String[] args) {Integer[] arr new Integer[]{7,8,9};List<Integer> list Arrays.asLi…

GIS算法:JAVA拓扑套件JTS

常用可以用于GIS数据处理和空间计算的java包有geotool和jts。 相对来说&#xff0c;geotool功能更全面&#xff0c;还可以用于数据转换、瓦片地图发布、栅格影像分析等&#xff0c;jts只能进行基本的数据处理和空间计算。 但大多数情况下jts就完全够用了。 geotool的官网&am…

Java本地远程服务器debug调试详解

日常我们debug是经常用的&#xff0c;但是本地还好说&#xff0c;远程debug就有点难度&#xff0c;而且有时候必须要在预演&#xff0c;测试环境的服务器去debug&#xff0c;举个例子&#xff0c;需要https&#xff0c;公网&#xff0c;域名之类的&#xff0c;测试服务器这些有…

Linux “ll“ 命令详解

“ls -l” “ls -al” ll 用来查询当前目录下文件及目录的详情 1.第一位文件类型 普通文件 &#xff0c; d 目录文件&#xff0c;I 链接文件&#xff0c;p 管理文件&#xff0c; b 块设备文件&#xff0c; c 字符设备文件&#xff0c; s 套接字文件 2.文件属性 第一部分表示文…

SpringBoot项目jar发布获取jar包所在目录路径

//第一种File path new File(ResourceUtils.getURL("classpath:").getPath());if(!path.exists()) path new File("");System.out.println(path.getAbsolutePath());//第二种System.out.println(System.getProperty("user.dir"));//第三种Stri…

路径classpath,classpath*,以及file:

./ 当前目录 …/上一层目录 /是根目录 1. classpath : 类路径&#xff0c;指的是编译后的字节码文件存储路径&#xff0c;一般为target目录下的classes目录&#xff08;java项目&#xff09;&#xff0c;在web项目中指的是WEB-INF下的classes目录。实际上&#xff0c;两者其实…

到底什么时候该使用MQ?

一、缘起 一切脱离业务的架构设计与新技术引入都是耍流氓。 引入一个技术之前&#xff0c;首先应该解答的问题是&#xff0c;这个技术解决什么问题。 就像微服务分层架构之前&#xff0c;应该首先回答&#xff0c;为什么要引入微服务&#xff0c;微服务究竟解决什么问题&…

Java中ByteArrayInputStream和ByteArrayOutputStream用法详解

Java中ByteArrayInputStream和ByteArrayOutputStream用法详解 这篇文章主要介绍了Java中ByteArrayInputStream和ByteArrayOutputStream用法详解&#xff0c; ByteArrayInputStream 的内部额外的定义了一个计数器&#xff0c;它被用来跟踪 read() 方法要读取的下一个字节 Byte…

Java中的Base64详解

详解Java中的Base64原理跟用法 简介 ​ Base64编码&#xff0c;是我们程序开发中经常使用到的编码方法。它是一种基于用64个可打印字符来表示二进制数据的表示方法。它通常用作存储、传输一些二进制数据编码方法, 也是MIME&#xff08;多用途互联网邮件扩展&#xff0c;主要用…

Java程序执行Linux命令

java程序中要执行linux命令主要依赖2个类&#xff1a;Process和Runtime 首先看一下Process类&#xff1a; ProcessBuilder.start() 和 Runtime.exec 方法创建一个本机进程&#xff0c;并返回 Process 子类的一个实例&#xff0c; 该实例可用来控制进程并获得相关信息。Proces…

ImageIO类说明

最近的项目中遇到ImageIO&#xff0c;因此记录下这个类的用法 一、ImageIO&#xff1a; 这个类中的方法都是静态方法&#xff0c;可以用来进行简单的图片IO操作 1、读入的三种方法 public static BufferedImage read(File input) File file new File("/Users/xixi/Docum…

java:图像(BufferedImage)色彩空间转换(灰度)暨获取图像矩阵数据byte[](sRGB/gray)

ColorConvertOp java.awt.image包下面有个类java.awt.image.ColorConvertOp,类名直译就是”颜色转换操作”。 顾名思义,它的作用就是将一个色彩空间(color space)的图像转换为另一个色彩空间的图像。有了这个神器我们就能轻易的将一张彩色图你像转换成灰度(gray)或其他色彩空间…

MyBatis-Plus updateById方法更新不了空字符串/null解决方法

最近遇到了Mybatis-Plus updateById()&#xff0c;更新某一个字段为null&#xff0c;却发现没有更新成功。记录一下 一、简介 因为最近在忙项目&#xff0c;好久都没有更新博客&#xff0c;最近在项目中刚好遇到一个问题&#xff0c;就是在使用MyBatis-Plus updateById&#…

Java 分割字符串的方法String.split()底层原理与使用

文章目录split()底层原理1.举例说明2.split源码分析3.API原解4.regex参数API原解5.limit参数介绍6.结果的验证7.此方法的使用split方法的使用split用法分析参数解释—regex参数解释—limit不同limit值的情况下的split结果验证扩展split()底层原理 1.举例说明 1.最普通的用法 …

HttpClient使用和详解

文章目录一、关于HttpClient二、HttpClient使用步骤详解1、创建一个HttpClient对象A、HttpCLientConnectionManagerB、HttpRoutePlannerC、RequestConfig2、创建一个Request对象3、执行Request请求4、处理response1&#xff09;关闭和entity相关的content stream2&#xff09;关…

你还在 Docker 中跑 MySQL?

容器的定义&#xff1a;容器是为了解决“在切换运行环境时&#xff0c;如何保证软件能够正常运行”这一问题。 目前&#xff0c;容器和 Docker依旧是技术领域最热门的词语&#xff0c;无状态的服务容器化已经是大势所趋&#xff0c;同时也带来了一个热点问题被大家所争论不以&…