成员变量,局部变量,方法局部变量区别和详解

2019-09-19 14:17:28

参考地址  关于java成员变量和局部变量

1、成员变量和局部变量简述


在Java语言里,根据定义变量位置的不同,可以将变量分成两大类:成员变量(存在于堆内存中,和类一起创建)和局部变量(存在于栈内存中,当方法执行完成,让出内存,让其他方法来使用内存)。二者的运行机制存在较大差异。




1.1成员变量


类变量从该类的准备阶段起开始存在,直到系统完全销毁这个类,类变量的作用域与这个类的生存范围相同;


而实例变量则从该类的实例被创建起开始存在,直到系统完全销毁这个实例,实例变量的作用域与对应实例的生存范围相同。


正是基于这个原因,可以把类变量和实例变量统称为成员变量。其中类变量可以理解为类成员变量,它作为类本身的一个成员,与类本身共存亡;实例变量则可以理解为实例成员变量,它作为实例的一个成员与实例共存亡。


只要类存在,类就可以访问类变量         类.类变量


只要实例存在,实例就可以访问实例变量        实例.实例变量


当然实例也可以访问类变量。但是需要注意的是因为实例不拥有类变量,所以通过实例来访问类变量进行操作,实际上是对类变量进行操作 ,当有其他实例来访问类变量时,访问的类变量是被对象访问操作过的类变量。


成员变量无需显示初始化,只要为一个类定义了类变量或实例变量,系统就会在这个类的准备阶段或创建该类的实例时进行默认初始化。


1.2局部变量


局部变量根据定义形式的不同,又可以分为如下三种:


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


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


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


一个变量只在一对{}中起作用。。


java允许局部变量和成员变量同名,如果方法中局部变量和成员变量同名,局部变量就会覆盖成员变量,如果需要在这个方法中引用被覆盖成员变量,则可使用this(对于实例变量)或类名(对于类变量)作为调用者来限定访问成员变量。


2、成员变量的初始化和内存中的运行机制


接下来以下面代码来举例说明成员变量的初始化和内存中的运行机制


 




 1 public class Person {

 2     public int num;

 3     public String name;

 4     

 5     public static void main(String[] args) {

 6         Person p1 = new Person();

 7         Person p2 = new Person();

 8         p1.num = 2;

 9         p2.num = 3;

10         p1.name = "张三";

11         p2.name = "李四";

12     }

13     

14 

15 }



 


当程序执行Person p1 = new Person();时,如果这行代码是第一次使用Person类,则系统通常会在第一次使用Person类时加载这个类,并初始化这个类,在类的准备 阶段,系统将会为该类的类变量分配内存空间,并指定默认初始值。当person类初始化完成后,系统内存中的存储示意图如下图所示。




 可以看出,当person类初始化完成后,系统将在堆内存中为Person分配一块内存空间,实际上是创建了一个类对象,在这块内存区里包含了保存num类变量的内存,并设置num的默认初始值为0。


系统接着创建了一个Person对象,并把这个Person对象赋给p1变量,Person对象包含了名为name的实例变量,实例变量是在创建实例时分配内存空间并指定初始值的。当创建了第一个person对象后,系统内存中的存储示意图如下图所示。




从上图可以看出num不属于对象,它属于类,所以创建第一个对象时并不需要为num分配内存空间,系统只是为name分配了内存空间,并指定初始值为null。


创建第二个对象p2时,由于在创建第一个对象时已经对类进行了初始化,所以在创建p2时对类进行初始化,对象的创建过程与第一个对象的创建过程没有什么区别。




第二个对象创建完成后,成员变量如上图所示在内存中存储。


**当程序需要访问类变量时,尽量使用类来作为主调,不要使用对象作为主调,这个可以避免产生歧义。


3、局部变量的初始化和内存中的运行机制


*局部变量必须经过显示初始化之后才能使用,系统不会为局部变量执行初始化。定义了局部变量以后,系统并没有给局部变量进行初始化,直到程序给这个局部变量赋给初值时,系统才会为这个局部变量分配内存空间,并将初始值保存到这块内存中。


*局部变量不属于任何类或者实例,因此它总是保存在方法的栈内存中。如果局部变量是基本数据类型,则该变量直接存储在方法的栈内存中,如果是引用变量则将引用的地址存储在方法的栈内存中。


*栈内存中的变量无需系统垃圾回收,随着方法或者代码块的运行结束而结束。局部变量通常只保存了具体的值或者引用地址,所以所占的内存比较小。


4、变量的使用规则


能不使用成员变量就别使用成员变量


能不使用方法局部变量就别使用方法局部变量


使用代码块局部变量性能最好。


  • 2019-11-29 13:47:22

    百度地图做电子围栏总结

    在地图上画出围栏,设置围栏信息后保存,生成围栏列表。全选时,地图视野可看到全部的围栏区域,单独勾选会调整地图视野到当前勾选的围栏。围栏区域的中心点要显示围栏名称。

  • 2019-11-29 13:50:29

    图片连接处出现白线

    block导致,只要父元素设置font-size:0或者设置img display: block; 便可。但是我设置了没有用,这条线不是所有的机型都有,而且页面滚动之后又消失,我琢磨半天,各种尝试,发现把图片高度减少(增加)1px就解决了。因为我们的项目是用postcss-px-to-viewport,我每张图片都是设置高度的,应该是数值转换出现偏差。

  • 2019-11-29 13:54:07

    粗略计算多边形中心点(并不是很准确,但简单好用)

    也是再做栅栏系统,搜索如何获取多边形中心点的问题上,发现了这个,简单易于理解,但是并不是特变准确,但也不影响使用。 后来发现了新的算法,并且百度地图也提供相应的api。 具体内容我写在了前面的文章,大家可以找一下。

  • 2019-11-29 14:20:38

    vue,vuthis.$parent算法

    由于组件嵌套,其实vue parent的位置也改变了,我们可以通过下面的图片,来看一下,parent到底什么哪一层

  • 2019-11-29 14:23:24

    百度地图 多个标记点设置最佳视角

    通过下面的语法,我们可以为不规则图形,以及过大的图形进行地图适配,更好的展示我们画的图形,当然,如果展示所有的图形,我们可以暴力的把所有的点组合起来进行展示,点过多不知道会不会影响性能,不过我们也可以从后台精简点数,不过地球是圆的,不知道好不好做。

  • 2019-12-01 08:00:16

    PHP中的HTTP_HOST和SERVER_NAME有什么区别

    多域名指向同一个php服务器,用nginx做代理,获取SERVER_NAME都是第一个域名,这就尴尬了,至今不明白咋回事,最后用HTTP_HOST解决都,这个暂时倒是准确。

  • 2019-12-01 08:04:30

    laravel多路由配置,也可以做根据域名都动态路由

    在用laravel 框架开发大型应用的时候,由于 laravel 默认是只有一个路由文件,如果把项目所有模块的路由放在一个路由文件下,那么该路由文件就显得很臃肿,以至于后期难以维护,解决方案是根据不同模块配置不同路由文件。