由static修饰的是类变量,类名.变量名 调用,也可以用对象.变量名调用
不是由static修饰的是实例变量,也就是对象成员变量, 对象.变量名 调用
public class Variable {
//定义类变量
private static String name ;;
//定义对象变量
private int age;
public static void main(String[] args){
Variable p1 = new Variable();
Variable p2 = new Variable();
p1.name = "panda";
p1.age = 16;
p2.name = "kongfu";
p2.age = 18;
System.out.println("-----"+Variable.name);
}
}
下面我们来逐步看内存情况
- Variable p1 = new Variable(); 第一次使用Variable这个类,系统会加载这个类,并且初始化,name为类变量,系统为类变量分配内存空间、并且赋初始值
- 类初始化完成后,系统会为Variable类创建一个对象,age属于实例变量,系统为age分配内存空间并指定初始值0,然后把Variable对象所在地址赋值给p1,即p1指向一个Variable对象。如下图
Variable p2 = new Variable();
执行这行代码过程基本和 Variable p1 = new Variable(); 一毛一样,只是Variable类已经存在堆内存中了,不需要再进行加载、初始化、如下图
p1.age = 16; p2.age = 18;
当执行这两行代码时,即通过引用给各自对象成员变量赋值,没啥说的;重点在于p1.name = "panda" p2.name = "kongfu";
这两行代码,通过对象来访问类变量并赋值,从上图可以看出,类变量归类管,在类的内存区中,对类的所有对象实例都是共享的,跟通过类来访问时一样的,所做的修改对所有对象都有影响,如下图
有猿友反应staic变量放得位置不对,
找了几篇资料,jdk8之前静态变量确实是放在方法区中,8是把字符串池和静态变量放入堆中
运行时常量池得变化:
字符串常量池和静态变量存放位置得变化: