成员变量和局部变量

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


原文地址:https://www.cnblogs.com/lc0605/p/13294380.html