Java类的成员变量和局部变量

在Java中,成员变量和局部变量存在较大的差异性。首先,我们来看一下变量的分类图:

成员变量

成员变量被分为:类属性和实例属性。

类属性:定义一个属性时,不使用static修饰的就是实例属性,

实例属性:定义一个属性时,使用static修饰的是类属性。

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

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

PS:一个类在使用之前,要经过类加载、类验证、类准备、类解析、类初始化等几个阶段。以上就是类的生命周期。

注意:成员变量无须显式初始化,只要为一个类定义了类属性或实例属性,则系统会在这个类的准备阶段或创建这个类的实例时,进行默认初始化,成员变量默认初始化时的复制规则与数组动态初始化时数组元素的赋值规则完全相同。

实例属性随实例的存在而存在,而类属性则随类的存在而存在。实例也可以访问类属性,同一个类的所有实例访问类属性时,实际上访问的是同一个类属性,因为它们实际上都是访问到该类的类属性。

局部变量

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

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

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

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

与成员变量不同的是,局部变量除了形参之外,都必须显示初始化。也就说,必须先给方法局部变量和代码块局部变量指定初始值,否则不可以访问它们。

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

当系统加载类或创建该类的实例时,系统自动为成员变量分配内存空间,并在分配内控空间后,自动为成员变量指定初始值。

public class Person {
	public String name;
	public static int age;

	public static void main(String[] args) {
		//创建第一个Person对象
		Person p1 = new Person();
		//创建第二个Person对象
		Person p2 = new Person();
		//分别为两个Person对象的name属性赋值
		p1.name="张三";
		p2.name = "李四";
		//分别为两个Person对象的eyeNum属性赋值
		p1.age = 20;
		p2.age = 30;
	}
}

当程序执行第一行代码Person p1 = new Person();时,如果这行代码是第一次使用Person类,则系统通常会在第一次使用Person类时加载这个类,并初始化这个类。

在类的准备阶段,系统将会为该类的类属性分配内存空间,并指定默认初始值。当Person类初始化完成后,系统内存中的存储示意图如下:

(初始化Person类后的示意图)

当Person类初始化完成后,系统将在堆内存中为Person类分配一块内存区(当Person类初始化完成后,系统会隐含地为Person类创建一个类对象),在这块内存区里包含了保存类属性eyeNum的内存,并设置eyeNum的默认初始值:0

接着,系统会创建一个Person对象,并把整个Person对象赋给P1变量,Person变量里包含了名为name的实例属性,实例属性是在创建实例时分配内存空间、并指定初始值的。

当创建了第一个Person对象时,系统内存中的存储如下:

(创建第一个Person对象后的示意图)

age类属性并不属于Person对象,它是属于Person类的,所以创建第一个Person对象时并没有为eyeNum类属性分配内存,系统只是为name实例属性分配了内存空间,并指定默认初始值:null。

接着执行 Person p2 =new Person();代码创建第二个Person对象,此时因为Person类已经存在于堆内存中了,所以不再需要对Person类进行初始化。

创建第二个Person对象与创建第一个Person对象并没有什么不同。

当程序执行 p1.name ="张三";代码时,将为p1的name属性赋值,也就是让上图中堆内存中name指向一个"张三"的字符串。

执行完成后,两个Person对象在内存中的示意图如下:

(为第一个Person对象的name属性赋值后的存储示意图)

从上图中可以看出:name属性是Person的实例属性,因此修改第一个Person对象的name属性时仅仅与该对象有关,与Person类和其他Person对象没有任何关系。同样,修改第二个Person对象的name属性时,也只修改这个Person对象的name属性,与Person类和其他Person对象无关。

直到执行p1.age=2;代码时,此时通过Person对象来修改Person的类属性,从图5.12中不难看出,Person对象根本没有保存age属性,通过p1访问的age属性,其实还是Person类的age属性。因此,此时修改的是Person类的age属性。修改成功后,内存中的示意图如下:

(设置p1.age的属性后的存储示意图)

通过P1来访问其类属性时,实际上访问的是Person类的age属性。事实上,所有Person实例访问age属性时,都将访问到person类的age。因此,不管是通过Person类访问age属性,还是铜鼓哦任何Person独享来访问age属性,所访问的是同一块内存,Person类和所有的Person对象的age属性都会随之改变。

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

局部变量定义后,必须经过显示初始化才能使用,系统不会为局部变量执行初始化。这意味着:

定义局部变量之后,系统并未为这个变量分配内存空间,直到等到程序为这个变量赋初始值时,系统才会为局部变量分配内存,并将初始值保存到这块内存中。

与成员变量不同,局部变量不属于任何类或实例,因此它总是保存在其所在方法的栈内存中的。

如果局部变量是基本类型的变量,则直接把这个变量的值保存在该变量对应的内存中;

如果局部变量是一个引用类型的变量,则这个变量里存放的是地址,通过改地址,引用到该变量实际引用的对象或数组。

栈内存中的变量无须系统垃圾回收,栈内存中的变量往往是随方法或代码块的运行结束而结束的。

因此,局部变量的作用域是从初始化该变量开始,到该方法或该代码块运行完成而结束。因此局部变量只保存基本类型的值或者对象的引用,因此局部变量所占的内存区通常非常小。

PS:成员变量时被放置到堆内存中的,而局部变量放置在栈内存中。

成员变量将被放置到堆内存中,成员变量的作用域扩大到类存在范围或者对象存在范围,有两个害处:

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

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-12 15:32:24

Java类的成员变量和局部变量的相关文章

【java基础】成员变量和局部变量

成员变量和局部变量 根据定义变量位置的不同,可以将变量分为成员变量和局部变量        成员变量是在类范围内定义的变量        局部变量是在一个方法内定义的变量   成员变量可以分为:        实例属性 (不用static修饰)               随着实例属性的存在而存在       类属性 (static修饰)               随着类的存在而存在   成员变量无需显式初始化,系统会自动对其进行默认初始化   局部变量可分为:        形参(形式参数)

在实例中说明java的类变量,成员变量和局部变量

java中一般有三种变量:类变量,成员变量和局部变量.类变量 1.下面先看类变量,看下面这个例子 public class Demo6{ public String name; public int age; public static String sex="男"; public Demo6(String name, int age){ this.name = name; this.age = age;; } public void say(){ System.out.println

【java基础】成员变量和局部变量02

成员变量和局部变量(2) 成员变量的初始化和内存中的运行机制         当系统加载类或者创建类的实例的时候,系统会自动为成员变量分配内存空间,并自动指定初始值. package object; public class Person { //定义一个静态的变量 public static String city; //定义一个非静态的变量 public String name; public static void main(String[] args) { /*当person类加载的时候

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

在类中的位置不同 成员变量:在类内部方法外部 局部变量:在方法体内部定义的或者方法的参数中定义的在内存中的位置不同 成员变量:在堆内存,有初始化值,byte,short,int,long->0,char->'\u0000',float,double->0.0,引用类型->null: 局部变量:在栈内存,没有初始化的值,必须初始化后才能使用.生命周期不同 成员变量:随着对象的创建而存在,随着对象的消失而消失 局部变量:随着方法的调用而存在,随着方法的调用完毕而消失初始化值不同 成员变

java类中成员变量初始化后存放在堆内存中还是栈内存中?

答案是堆内存. 之前明明看过java类初始化过程的, 但一下子看到这样的题目,还是懵了. 百度后,那些帖子的回复各有各说, 脑袋都看得要塞住了,还是看书求证吧. 李刚的<疯狂Java>第128页开始,有一个类从初始化开始, 在内存发生什么变化的详细过程,这里简单记录一下. class Person{     String name;     static int eyeNum; } 上面这个Person类,有成员变量name和静态成员变量eyeNum了, 当执行下面语句: Person p1 

java中的成员变量和局部变量的区别

成员变量: 在类体里面定义的变量叫做成员变量: 如果在变量有static关键字修饰,就叫作静态变量或类变量: 如果该变量没有static关键字修饰,就叫作非静态变量或实例变量: 局部变量: 方法内定义的变量.形参.代码块中定义的变量都叫做局部变量: 另外,成员变量可以不显式初始化,它们可以由系统设定默认值:局部变量没有默认值,所以必须设定初始赋值. 还有,在内存中的位置也不一样.成员变量在所在类被实例化后,存在堆内存中:局部变量在所在方法调用时,存在栈内存空间中. 原文地址:https://ww

java中的成员变量,局部变量的理解

首先我们来理解什么是变量,依我来看,变量就是用来存放值的一个名字或者引用,比如年龄,性别,班级,学号,身份证号码等等.对于不同的对象当然有不一样数值.变量也有自己的属性,比如整数型,字符串类型,浮点型等等,基本数据类型和引用数据类型都可以.一个类里面有属性和方法,局部变量和成员变量的区别就输成员变量在类里面的作用区域是在整个类中使用.局部变量是指在方法里面的变量,作用域只在方法里面. 原文地址:https://www.cnblogs.com/yindong2019/p/11780599.html

JAVA中的成员变量与局部变量

package com.imooc; //1.定义一个类 public class Telphone { //2.属性(成员变量)有什么 float screen; float cpu; float mem; int var = 30; //3.方法干什么 void call(){ int var = 40; int localVar=0; System.out.println("var:"+var); System.out.println("loclaVar:"+

第3章 Java语言基础 成员变量与局部变量

在对局部变量进行赋值时,不能对非静态字段age进行静态引用,如下图所示: