成员变量与局部变量

成员变量与局部变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Demo1 {
static int s;
int i;
int j;
{
int i = 1;
i++;
j++;
s++;
}
public void test(int j) {
j++;
i++;
s++;
}
public static void main(String[] args) {
Demo1 obj1 = new Demo1();
Demo1 obj2 = new Demo1();
obj1.test(10);
obj1.test(20);
obj2.test(30);
System.out.println(obj1.i + "," + obj1.j + "," + obj1.s);
System.out.println(obj2.i + "," + obj2.j + "," + obj2.s);
}
}

执行结果:

2,1,5
1,1,5

考点:

  • 就近原则

  • 变量的分类

    • 成员变量:类变量、实例变量

    • 局部变量

  • 非静态代码块的执行:每次创建实例对象都会执行

  • 方法的调用规则:调用一次执行一次

局部变量与成员变量的区别:

  • 值存储的位置

    • 局部变量:栈

    • 实例变量:堆

    • 类变量:方法区,与类相关联,仅存一份

  • 作用域

    • 局部变量:从声明处开始,到所属的 } 结束

    • 实例变量:在当前类中“this.”(有时this.可以缺省),在其他类中“对象名.”访问

    • 类变量:在当前类中“类名.”(有时类名.可以省略),在其他类中“类名.”或“对象名.”访问

  • 生命周期

    • 局部变量:每一个线程,每一次调用执行都是新的生命周期

    • 实例变量:随着对象的创建而初始化,随着对象的被回收而消亡,每一个对象的实例变量是独立的

    • 类变量:随着类的初始化而初始化,随着类的卸载而消亡,该类的所有对象的类变量是共享的

分析:

一、运行 main 方法,开始执行类初始化方法<clinit>(),该方法由静态类变量显示赋值代码、静态代码块组成,在此用例中,只有静态变量赋值语句:static int s; 类变量 s 存在于方法区中,该类的所有实例共享这一份变量

此时 s = 0

二、line1: Demo1 obj1 = new Demo1(); 创建实例,执行 <init>(),该方法由非静态变量显示赋值代码、非静态代码块、构造器组成,此用例中根据顺序先执行非静态变量显示赋值代码,然后执行非静态代码块,构造器无赋值语句可忽略。创建 obj1 对象,在堆中开辟了一份 obj1 实例的内存空间,保存着 i、j 两个实例变量

非静态变量显示赋值代码执行后:
obj1.i = 0
obj1.j = 0
--------------------------
非静态代码块执行后:
// i 还是为0,根据就近原则,非静态代码块中的自增的变量 i 不是实例变量i,而是局部变量i,代码块结束之后该变量消亡
obj1.i = 0
obj1.j = 1
Demo.s = 1 // 共享变量,类变量

三、line2: Demo1 obj2 = new Demo1(); 创建实例,执行 <init>() 后,实例变量和 obj1 一样,但是类变量发生变化

obj2.i = 0
obj2.j = 1
Demo.s = 2 // 由于是共享变量,此时类变量递增为2

四、line3: obj1.test(10); main 方法传了形参 10 的值给 test 方法,JVM 为 test() 在栈中开辟了一个空间存储局部变量 j ,由于未指明自增的 j 是哪个变量,根据就近原则,给局部变量 j 自增为 11,然后再给obj1的其他实例变量赋值

obj1.i = 1 // 自增1
obj1.j = 1 // 自增的局部变量j,要想指定自增实例变量,可以通过指定 this.j++
Demo.s = 3 // 继续自增

五、line4: obj1.test(20);

obj1.i = 2 
obj1.j = 1 
Demo.s = 4

六、line5: obj2.test(30);

obj2.i = 1
obj2.j = 1
Demo.s = 5

每创建一个Demo的实例,就会在堆中开辟新的这个该对象实例的变量空间,不同实例变量之间互不影响,随着实例的回收而消亡,但是类变量是独有一份的,每个实例操作的是同一份。故此时 obj1 和 obj2 的输出:

obj1.i = 2 
obj1.j = 1 
obj1.s = 5 // 类变量也可以通过实例引用调用

obj2.i = 1
obj2.j = 1
obj2.s = 5

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×