1.数组的初始化:
静态初始化: 程序员在初始化数组时为数组每个元素赋值;
动态初始化: 数组初始化时,程序员只指定数组的长度,由系统为每个元素赋初值。
1 public class ArrayInit { 2 public static void main(String[] args) { 3 //String[] str = new String[]; 4 //这样初始化数组是错误的.和String字符串是不一样的. 5 //数组初始化最起码要指定长度. 6 7 //静态初始化数组:方法一 8 String cats[] = new String[] { 9 "Tom","Sam","Mimi" 10 }; 11 //静态初始化数组:方法二 12 String dogs[] = {"Jimmy","Gougou","Doggy"}; 13 14 //动态初始化数据 15 String books[] = new String[2]; 16 books[0] = "Thinking in Java"; 17 books[1] = "Effective Java"; 18 19 System.out.println(cats.length); 20 System.out.println(dogs.length); 21 System.out.println(books.length); 22 } 23 }
2.数组是否必须初始化
对于这个问题,关键在于要弄清楚数组变量和数组对象的差别。数组变量是存放在栈内存中的,数组对象是存放在堆内存中的。数组变量只是一个引用变量,它能够指向实际的数组对象。
所谓的数组初始化并非对数组变量初始化,而是对数组对象进行初始化。
数组必须要有其长度。
关于内存的划分:
内存的划分
1. 寄存器 CPU处理的。
2. 本地方法区 所在系统相关的。 java的jvm分版本,不同的系统,不同的jvm。
3. 方法区 以后讲。。。现在还没有接触到更多的类加载方式。
4. 栈内存
存储的都是局部变量。(方法中的变量都是局部变量)
变量所属的作用用户一旦结束,该变量就自动释放
栈内存的更新速度很快,因为局部变量的生命周期都比较短
5. 堆内存
存储是数组和对象(其实数组就是对象) 凡是new建立在堆中。
特点:
1. 每一个实体都有一个首地址值。
2. 堆内存中的每一个变量都有一个变量默认初始化值,
根据类型的不同而不同,整数是0,小数是0.0或者0,0f。boolean是false
char类型是’u0000’(带转义字符,是unicode编码,是空格的意思)
3. 垃圾回收机制。
关于下面语句的分析:
int [] arr = new int [3];
arr 是局部变量,在主函数中,(局部变量在栈中,局部变量又在主函数中,所以主函数也在栈中,方法不进栈,局部变量也无法进栈)。
new int[3] 是数组对象,在堆内存中,是实体,是实实在在存储的个体。实体就是用来封装数据,而且可以用来封装多个。实体中有一堆数据,有一个挂了,其他的还可以用,
但是栈内存中都是存储的变量,挂了接着消失。堆内存中的实体中变量会默认初始化值,栈内存不会默认初始化,不同类型初始化的内容是不一样的。
如果想让arr不做任何指向,给arr=null,就取消了arr的指向。
这样之前的指向就取消了,之前指向的内容不会在堆内存中自动释放,而是作为垃圾在堆内存中,java中有垃圾回收机制是一段程序,至于什么时候去回收不知道。
优秀的内存管理机制。但是c++中的垃圾是由程序员手动去处理垃圾。是由析构函数来处理的,否则在内存中会越积越多。多了就挂了。。。
关于int [] arr = new int [3];内存分析图:
分析图二:
多个实体可以指向同一个对象。
数组越界和空指针异常是数组中经常遇到的异常
ArrayIndexOutofBounds 和 NullPointException
直接打印数组对象,打印出来的是打印出的是数组实体的哈希值。
System.out.println(arr)@**** [I@52e922 [F@52e922
哈希是一种算法,由这种算法来定义数组实体在内存中的位置,可以简单的理解为地址值。
但是在javascript中个直接打印数组对象arr可以直接打印出数组中的内容(貌似是字符串的方式,数组中的每个元素之间还有逗号隔开,这是和java不同的地方。
关于哈希值:
该地址值是由windows来支持的,java是通过调用windows的这种哈希编码方式来算出其位置
最终开辟内存空间是windows说了算。
哈希值是十六进制值
@的左边是实体的类型 带中括号是数组类型 有字母I是Int类型
@的右边不用看,只看左边就能知道是什么类型的实体
进制越大表现形式越短。内存地址都是用十六进制来表示的。