今天去面试遇到了有关成员变量与局部变量以及成员方法的问题,主要是涉及所处内存的问题和初始化问题,简单的总结一下:
1.java中成员变量处在堆内存(成员方法不调用时存在方法区中的静态区)中,局部变量处在栈内存中;
知其然知其所以然,我们简单了解一下Java内存分配:
一个完整的Java程序运行过程会涉及以下内存区域:
寄存器:JVM内部虚拟寄存器,存取速度非常快,程序不可控制。
***堆:***用来存放动态产生的数据,比如new出来的对象。注意创建出来的对象只包含属于各自的成员变量,并不包括成员方法。因为同一个类的对象拥有各自的成员变量,存储在各自的堆中,但是他们共享该类的方法,并不是每创建一个对象就把成员方法复制一次。类的方法是所有的同类对象共享的,方法是存在方法区的(下面会有对方法区的介绍),只用当调用的时候才会被压入栈,不用的时候只占用方法区的内存
栈:保存局部变量的值,包括:1.用来保存基本数据类型的值(注意“的值”二字);2.保存类的实例,即堆区对象的引用(指针)。也可以用来保存加载方法时的帧。存储在堆中的对象是全局可以被访问的,然而栈内存不能被其他线程所访问。
对于局部变量,如果是基本类型,会把值直接存储在栈;如果是引用类型,比如String s = new String(“william”);会把其对象存储在堆,而把这个对象的引用(指针)存储在栈。
再如
String s1 = new String(“william”);
String s2 = s1;
s1和s2同为这个字符串对象的实例,但是对象只有一个,存储在堆,而这两个引用存储在栈中。
类的成员变量在不同对象中各不相同,都有自己的存储空间(成员变量在堆中的对象中),基本类型和引用类型的成员变量都在这个对象的空间中,作为一个整体存储在堆。而类的方法却是该类的所有对象共享的,只有一套,对象使用方法的时候方法才被压入栈,方法不使用则不占用内存。
方法区: JAVA 方法区与堆–java7前,java7,java8各不相同(可点击查看)
方法区又被称为静态区,是程序中永远唯一的元素存储区域。和堆一样,是各个线程共享的内存区域。它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
Java虚拟机规范对方法区的限制非常宽松,除了和Java堆一样 不需要连续的内存和可以选择固定大小或者可扩展之外,还可以选择不实现垃圾回收。
这区域的内存回收目标主要是针对常量池(已经在jdk1.7后被转移到堆)的回收和类型的卸载,一般而言,这个区域的内存回收比较难以令人满意,尤其是类型的回收,条件相当苛刻,但是这部分区域的内存回收确实是必要的(所以开发新项目尽量使用1.7以上的版本)。
很多开发者更愿意把方法区称为“永久代”(Perm Gen)(Permanent Generation)「总是存放不会轻易改变的内容」。在目前已经发布的JDK 1.7 的HotSpot中,已经把原本放在永久代的字符串常量池移至堆中。
运行时常量池(Runtime Constant Pool)是方法区的一部分。
常量池:JVM为每个已加载的类型维护一个常量池,常量池就是这个类型用到的常量的一个有序集合。包括直接常量(基本类型,String)和对其他类型、方法、字段的符号引用。池中的数据和数组一样通过索引访问。由于常量池包含了一个类型所有的对其他类型、方法、字段的符号引用,所以常量池在Java的动态链接中起了核心作用。jdk1.7以后常量池存在于堆中。
代码段:用来存放从硬盘上读取的源程序代码。
数据段:用来存放static定义的静态成员。
最后我们来个栈堆的区别总结:
堆内存和栈内存的区别
基于上边的解释我们可以很简单的总结出堆和栈的区别:
1、应用程序所有的部分都使用堆内存,然后栈内存通过一个线程运行来使用。
2、不论对象什么时候创建,他都会存储在堆内存中,栈内存包含它的引用。栈内存只包含原始值变量好和堆中对象变量的引用。
3、存储在堆中的对象是全局可以被访问的,然而栈内存不能被其他线程所访问。
4、栈中的内存管理使用LIFO的方式完成,而堆内存的管理要更复杂了,因为它是全局被访问的。堆内存被分为,年轻一代,老一代等等,更多的细节请看,这篇文章
5、栈内存是生命周期很短的,然而堆内存的生命周期从程序的运行开始到运行结束。
6、我们可以使用-Xms和-Xmx JVM选项定义开始的大小和堆内存的最大值,我们可以使用-Xss定义栈的大小
7、当栈内存满的时候,Java抛出java.lang.StackOverFlowError异常而堆内存满的时候抛出java.lang.OutOfMemoryError: Java Heap Space错误
8、和堆内存比,栈内存要小的多,因为明确使用了内存分配规则(LIFO),和堆内存相比栈内存非常快。
2.成员变量调用前可以不用初始化,变量创建后有默认初始值成员变量:有默认初始化值
局部变量:没有默认初始化值,必须定义,赋值,然后才能使用。
---------------------
作者:www.kingyase.com
来源:CSDN
原文:https://blog.csdn.net/weixin_42206151/article/details/84781368
版权声明:本文为博主原创文章,转载请附上博文链接!
相关推荐
4. **this关键字**: 在方法中,使用`this`关键字可以引用当前对象的成员变量,以区分方法参数或其他局部变量。 **局部变量** 局部变量是在方法、构造器或初始化块中声明的变量。它们只在声明它们的代码块内有效,...
以下是关于Java成员变量、局部变量、静态变量以及成员方法和全局方法的基本概念和区别的详细阐述。 1. 成员变量(Member Variables): 成员变量是类的一部分,它们定义了对象的状态。它们可以是实例变量(非静态...
Java编程语言中有三种主要的变量类型:成员变量(也称为实例变量)、类变量(也称为静态变量)和局部变量。...因此,理解Java成员变量、类变量和局部变量之间的区别对于成为一名专业的Java开发者至关重要。
Java编程语言中有两种主要的变量类型:成员变量和局部变量,它们在定义、作用范围、默认值、内存位置以及生命周期方面都有所不同。 首先,**定义的位置**是两者最基本的区别。成员变量,也称为实例变量,是定义在类...
在类中的位置不同 成员变量:在类中方法外 局部变量:在方法内或者方法声明处 在内存中的位置不同 成员变量:在堆内存中 局部变量:在栈内存中 ... 成员变量和局部变量的名称可以一致,方法调用的时候采取就近原则
Java程序基础成员变量和局部变量 Java程序基础成员变量和局部变量是Java程序设计中两个基本概念。成员变量是类的属性,跟对象一起出生和消失,而局部变量是函数的一部分,随着函数一起运行和结束。 成员变量是表明...
Java 局部变量与成员变量的区别 Java 编程语言中,变量是非常重要的一部分,它们可以存储不同的数据类型的值,並在程序中发挥着重要的作用。在 Java 中,变量可以分为两大类:局部变量和成员变量。这两种变量有着...
Java中的成员变量与局部变量是编程中非常基础且重要的概念,它们在程序设计中起到不同的作用,理解并熟练掌握这两者之间的区别对于编写高质量的Java代码至关重要。 成员变量(Member Variables)是类的属性,它们...
2. **生命周期**:成员变量的生命周期与对象相同,局部变量的生命周期与方法或代码块相同。 3. **默认值**:成员变量有默认值,而局部变量没有。 ##### 成员变量与静态变量的区别: 1. **生命周期**:成员变量随...
在面向对象设计中,合理地分配状态到对象的成员变量,以及在方法中使用局部变量来处理临时数据,是实现良好软件设计原则的关键步骤之一。 总的来说,面向对象编程中的成员变量和局部变量是两个基础但至关重要的概念...
这意味着如果你在方法中引用一个与成员变量同名的变量,实际上是在引用局部变量。例如,在 `run()` 方法中,即使有同名的成员变量 `color`,`this.color` 会引用成员变量,而 `carName` 是局部变量,两者不会混淆。 ...
局部变量的生存时间和方法的生存时间是一致的,调用该方法时该局部变量被创建并分配内存空间,当方法调用结束时局部变量也就结束了。局部变量在使用前必须进行初始化,系统默认不会对局部变量进行初始化数据操作,...
在Java编程语言中,成员变量和局部变量是两种基本的变量类型,它们在功能、作用域和生命周期上有显著的区别。 **成员变量(Member Variables)**: 成员变量是类的组成部分,它们定义在类的主体中,但不在任何方法...
本文将深入探讨静态变量、成员变量(也称为实例变量)以及局部变量之间的主要区别。 首先,我们来看静态变量和成员变量的区别: A. 所属关系: 静态变量是属于类的,这意味着它们是类级别的变量,所有该类的对象都...
局部变量在方法内声明,只在该方法内部有效。成员变量在类中声明,可以在类的任何地方访问。 ### 常量与变量的使用规范 - 常量通常使用大写字母表示,单词间用下划线连接,如`MAX_VALUE`。 - 变量名应具有描述性,...
方法中的变量有不同作用域:成员变量在整个类内有效,局部变量只在其定义的方法或块内有效,方法参数在其所属的方法或构造器内有效,而异常处理参数则局限于特定的异常处理代码。 构造方法是与类同名的方法,用于...