Java数组是静态的—由于java语言是静态的java
静态是指,当一个数组被初始化了以后,其长度是不可变的,而且数组必须通过初始化才能使用。(见下面特例)数组
int[] int_arr_3 = null; //int_arr_3指向null,可是因为未访问其引用的数组对象,因此这句不会报NullPointer System.out.println(int_arr_3); //使用int_arr_3.length,访问了该数组所引用的对象,因此会报空指针 //System.out.println(int_arr_3.length);
静态初始化:初始化的时候指定初始值,由系统决定长度spa
int[] int_arr_1 = new int[]{43,56,74,23,25};指针
动态初始化:初始化时只指定长度,由系统分配初始值code
int[] int_arr_2 = new int[5];对象
指定的初始值规则以下:内存
不要同时使用静态初始化和动态初始化~!it
数组中的元素类型一致内存管理
数组变量是引用类型的变量,如图:class
a1,a2,a3是三个数组,位于栈内存,他们都是引用类型变量,指向的是对内存的数组对象,因此当数组被初始化之后,堆内存里面的数组对象长度就不可变了,可是能够将数组指向(引用)其它的数组对象,形成数组可变的假象
那么在这里能够想象,数组不必定要初始化,由于他是引用变量,那么当他被声明以后(只是被分配了栈内存),只要让数组元素指向有效的数组对象(至关于初始化),那么该数组就能够被使用。
int arr = new int[]{1,2};
arr指的是数组,而若是arr经过引用访问属性或者调用方法,那么此时的数组就是数组对象自己。
int a = 10;
int b = 20;
arr[0] = a;
b = arr[1];
都是能够的
在已有的数组类型后面加上[],即产生了一个新数组
同理,将数组最后面的[]去掉,即获得了该数组存储的类型
因此,数组元素就是变量
多维数组
int a[][]
考虑到数组是引用类型,因此多维数组便是一维数组的每一个元素引用的是另一个(一维)数组,看起来就成了多维数组
内存管理分为两个方面:
内存分配和内存回收
内存分配:建立java对象时,JVM为该对象在堆内存里分配内存空间
内存回收:当java对象失去引用以后,变成“垃圾”,将会被JVM清理
实例变量和类(静态)变量
实例变量分为局部变量和成员变量
局部变量:
类体内定义的变量称为成员变量(Field),其又分为非静态变量和静态变量
//下面的代码将提示:非法向前引用
int num1 = num2 + 2;
int num2 = 20;
//下面正常
int num1 = num2 +2;
static num2 = 20;
在同一个JVM内,每个类只对应一个Class对象,故只须要一块内存空间,可是却能够建立多个类对象,每建立一个对象,就要为该对象分配内存空间。
因此,类(静态)变量会在类初始化的时候初始化,分配内存,而建立对象的时候则不会再为静态变量分配内存了,只会为非静态类变量分配内存。
静态变量不能够访问非静态变量,可是非静态变量却能够访问静态变量,而且,也能够经过对象实例来访问静态变量,和经过类来访问效果同样
执行顺序
JVM对每个类只执行一次初始化操做,只为类变量分配一次内存空间,执行一次初始化
有两个地方对类变量执行初始化:
1:定义类变量是执行初始值
2:在静态初始化块中对类变量执行初始化
执行顺序与他们在代码中的顺序一致
代码分析:
程序输出值不是两个17.2,而是-2.8和17.2
分析:
首先将初始化分为两个步骤:
1:系统为price的两个类变量分配内存空间
2:按初始化代码的排列顺序对类变量初始化
第一阶段:系统先为INSTANCE,price分配内存空间,此时他们的默认值都是0.0
第二阶段:程序按顺序分别为他们赋值,首先是INSTANCE,他的值是new Price(2.8),即建立Price实例,调用构造方法:0.0 – 2.8 = -2.8,注意此时的initPrice是0.0~!!!,那么获得的currentPrice是-2.8,而后程序再对initPrice赋值:20,可是此时initPrice对INSTANCE已经没有影响了~!
当Price类初始化完成以后,INSTANCE引用到的currentPrice为-2.8,即输出-2.8,当再次构造Price对象,此时InitPrice为20.0,因此获得currentPrice为17.2