成员变量和局部变量
在介绍成员变量和局部变量之前,先看一段简单的代码,如果不能很明确的给出答案的话,请看完全文。
package com.ljw.field;
/**
* Created by liujiawei on 2018/7/17.
*/
public class TestFields {
public static String str = "实例变量";
static {
str = "代码块中的局部变量";
System.out.println("这个时候的str对象是" + str);
}
public static void main(String[] args) {
str = "方法中的局部变量";
System.out.println("这个时候的str对象是" + str);
System.out.println("这个时候的str对象是" + TestFields.str);
}
}
运行结果:
java中,根据变量定义位置的不同来区分变量,主要分为成员变量和局部变量,具体的结构用下图进行概括:
- 成员变量和局部变量理解
我们知道java加载类有一个缓存机制,也就是每一个类只会被加载一次,然后就会将这个类编译的class被放到缓冲区中,其中成员变量的类变量使用static修饰符进行修饰,不需要实例化对象就可以访问,也就是说在jvm完成类的初始化的时候,类变量就已经被赋值保存在堆中了,而实例变量需要通过对象来进行访问,也就是实例变量的值是随着对象保存在堆中对应的位置,每个对象都有属于自己的堆空间。举个例子:
package com.ljw.field;
/**
* Created by liujiawei on 2018/7/18.
*/
public class A {
public static String type = "A";
String name;
public static void main(String[] args) {
System.out.println(A.type);
A a = new A();
a.name = "a";
A a2 = new A();
a2.name = "a2";
}
}
一个A类,里面声明了两个成员变量,一个是类变量,一个是实例变量,main方法中,new了两个A的实例,分别设置了name属性,我们看下在内存中存储是怎样的:
当通过A类首次访问类变量type时,jvm会加载这个类,同时为类变量完成初始化,通过new A()的方式实例对象时,会在堆中重新分配一块区域用来存放对象,为实例对象分配内存,分配默认值。如图所示。而局部变量只会在栈中分配空间,方法结束空间随之释放。
2.成员变量和局部变量的区别
(1)定义的位置不同;
(2)生命周期不同,类变量随着类对象,成员变量随着对象,局部变量随着方法;
(3)在内存保存位置不同,成员变量在堆中,局部变量在栈中
(4)初始化不同,成员变量因为保存在堆中,所以jvm会分配默认值,局部变量需要自己完成初始化。