成员变量和局部变量
1、局部变量和成员变量的区别
1、声明的位置
局部变量:方法体{}中,形参,代码块中
成员变量:类中方法外
①、类变量:有static修饰
②、实例变量:没有static修饰
2、修饰符
局部变量:final
成员变量:public private protected final static volatile transient
3、值存储的位置
局部变量:栈
实例变量:堆
类变量:方法区
4、作用域
局部变量:从声明处开始,到所属“}”结束
实例变量:在当前类中用“this.”(有时this.省略)访问,在其他类中用“对象名.”访问
类变量:在当前类中用“类名.”(有时类名.省略)访问,在其他类中用“类名.”或“对象名.”访问
5、生命周期
局部变量:每一个线程,每一次调用都会有新的生命周期
实例变量:随着对象的创建而初始化,随着对象的被回收而消亡,每一个对象的实例变量是独立的
类变量:随着类的初始化而初始化,,随着类的卸载而消亡,该类的所有对象的类变量是共享的
public class Exam5 { static int s;//成员变量,类变量 int i;//成员变量,实例变量 int j;//成员变量,实例变量 { int i = 1;//局部变量 非静态代码块中的 i i++; j++; s++; } public void methed(int j) {//局部变量 形参 j j++; i++; s++; } public static void main(String[] args) {//局部变量 形参 args Exam5 obj1= new Exam5();//局部变量 ,test1 Exam5 obj2= new Exam5();//局部变量 ,test2 obj1.methed(10); obj1.methed(20); obj2.methed(30); System.out.println(obj1.i + "," + obj1.j + "," + obj1.s); System.out.println(obj2.i + "," + obj2.j + "," + obj2.s); } }
执行流程:
就近原则
①、main方法所在类需要先加载和初始化:执行类初始化(静态变量和静态代码块),static int s =0,成员变量的类变量,存放在方法区,共享
②、实例初始化:Exam5 obj1 = new Exam5()
栈中存储obj1,存储指向堆中实例的地址,堆中存储Exam5()对象本身,执行的是obj1的<init>()
<1>、非静态类变量显示赋值代码:int i=0; int j=0;成员变量的实例变量,存储在堆中,同对象实例存储在一起
<2>、非静态代码块:int i = 1;局部变量,存储在栈中;i++;就近原则,是非静态代码块中的i自增,故栈中的i=2;
j++;就近原则,是刚创建的实例对象中的j自增,故obj1指向的实例对象中的j=1;
s++;就近原则,是类初始化的成员变量(类变量)中的s自增,故方法区中的s=1;
<3>、构造器,该类未对构造器做任何操作
运行结束,局部变量i的生命周期结束,释放掉栈中的i=2
③、实例初始化:Exam5 obj2 = new Exam5()
栈中存储obj2,存储指向堆中实例的地址,堆中存储Exam5()对象本身,执行的是obj1的<init>()
<1>、非静态类变量显示赋值代码:int i=0; int j=0;成员变量的实例变量,存储在堆中,同对象实例存储在一起
<2>、非静态代码块:int i = 1;局部变量,存储在栈中;i++;就近原则,是非静态代码块中的i自增,故栈中的i=2;
j++;就近原则,是刚创建的实例对象中的j自增,故obj1指向的实例对象中的j=1;
s++;就近原则,是类初始化的成员变量(类变量)中的s自增,故方法区中的s=2;
<3>、构造器,该类未对构造器做任何操作
运行结束,局部变量i的生命周期结束,释放掉栈中的i=2
④、obj1.test(10);
执行test(int j)方法,int j是形参,局部变量,存储在栈中,j=10;
j++;就近原则,是栈的j自增,故栈中的j=11;
i++;就近原则,就近原则,是obj1的实例对象中的i自增,故obj1指向的实例对象中的i=1;
s++;就近原则,是类初始化的成员变量(类变量)中的s自增,故方法区中的s=3;
运行结束,局部变量j的生命周期结束,释放掉栈中的j=11
⑤、obj1.test(20);
执行test(int j)方法,int j是形参,局部变量,存储在栈中,j=20;
j++;就近原则,是栈的j自增,故栈中的j=21;
i++;就近原则,就近原则,是obj1的实例对象中的i自增,故obj1指向的实例对象中的i=2;
s++;就近原则,是类初始化的成员变量(类变量)中的s自增,故方法区中的s=4;
运行结束,局部变量j的生命周期结束,释放掉栈中的j=21
⑥、obj2.test(30);
执行test(int j)方法,int j是形参,局部变量,存储在栈中,j=30;
j++;就近原则,是栈的j自增,故栈中的j=21;
i++;就近原则,就近原则,是obj2的实例对象中的i自增,故obj2指向的实例对象中的i=1;
s++;就近原则,是类初始化的成员变量(类变量)中的s自增,故方法区中的s=5;
运行结束,局部变量j的生命周期结束,释放掉栈中的j=11
⑦、obj1.i为堆中实例对象所包涵的i,此时i=2;
obj1.j为堆中实例对象所包含的j,此时j=1;
obj1.s为方法区中共享的s,此时s=5;
obj2.i为堆中实例对象所包涵的i,此时i=1;
obj2.j为堆中实例对象所包含的j,此时j=1;
obj2.s为方法区中共享的s,此时s=5;
故,结果为:
2,1,5 1,1,5