写在前面
经过一段时间的java开发学习,发现自己的根基还不是很稳固。于是找了传智播客的网课来进行一个细致和系统一点的学习。希望能通过这个过程稳固一下自己的java基础。(本博客出现的图片均为传智播客网课内的图片)
数组
数组的初始化
对于数组的初始化,有两种方式:静态初始化和动态初始化。但需要记住的是不管是哪种方式在程序运行过程中数组的长度都是固定的,无法改变的。如下示例代码:
/**
* 学习数组的初始化
* 1.动态初始化(指定长度)
* 2.静态初始化(指定内容)
* 动态初始化数组的格式:
* 数据类型[] 数组名称 = new 数据类型[数组长度];
* 静态初始化数组的格式:
* 数据类型[] 数组名称 = new 数据类型[]{元素1,元素2,...};
* 数组是一定有长度的.
* 3.省略格式(静态初始化基础上)
* 数据类型[] 数组名称 = {元素1,元素2,...};
* Tips:
* 1.初始化的标准步骤可以拆分为两个步骤(即先声明后定义)
* 2.静态初始化的省略格式不能拆分
*/
private static void testInit() {
/* 动态初始化 */
// 创建一个数组,里面可以存放300个int数据
int[] arrayA = new int[300];
// 创建一个数组能存放10个double数据
double[] arrayB = new double[10];
/* 静态初始化 */
// 创建一个数组里面为5,15,25
int[] arrayC = new int[]{5, 15, 25};
// 创建一个数组里面放字符串:"hello"、"world","java"
String[] arrayD = new String[]{"Hello", "World", "Java"};
/* 省略格式 */
int[] arrayE = {10,20,30};
/* 拆分 */
int[] arrayF;
arrayF = new int[]{11,21,32};
// int[] arrayG;
// arrayG = {10,20,30};
}
数组的使用
数组的基础使用十分简单,只要在数组名后加上中括号,里面写上下标即可。这里说一下动态初始化时的默认值:
/**
* 学习数组的使用
* 直接打印数组名称,得到的是数组对应的内存地址哈希值
* 数组名称[索引值]
* 索引值从0开始.
* 使用动态初始化时,其中的元素会自动拥有一个默认值
* 整数类型,默认为0,浮点类型,默认为0.0,字符类型,默认为:"\\u0000";布尔类型,默认为false
* 引用类型,默认为null
* Tips:静态初始化也有默认值的过程,但会被替换为我们提供的具体数值
*/
private static void testUse(){
int[] array = {10,20,30};
// System.out.println(array);
System.out.println(array[0] + " " + array[1] + " " + array[2]);
System.out.println("==============");
int num = array[1];
System.out.println(num);
/*
动态初始化
*/
System.out.println("==========");
int[] arrayB = new int[3];
System.out.println(array[0]);
arrayB[1] = 150;
System.out.println("arrayB = " + arrayB[1]);
}
通过动态初始化,每个类型都有对应的初始化值。这里需要注意的是null,null是所有引用类型的默认值,他不是一种对象也不是一种类型,仅是一种特殊的值。
数组的内存结构
首先我们要了解,java中的内存分为了五片,如下图:
在这五片中,我们需要重点关注前三片。那么具体的数组运行过程的内存是如何使用的呢,先看图:
在程序的运行过程中,方法区存放着我们的方法定义,堆中存放着我们new申请的内存空间,如图我们new了一个数组,即是在堆(Heap)中申请了一块内存空间,赋值给我们定义的数组就是我们定义的数组指向了那一块内存空间。(我们自己定义的数组(变量)存放在栈(Stack)中)当我们修改其中的值时,就是将地址指向的值进行了一个修改。
对象
对于对象的定义,使用等等都很熟悉了,这里主要来看一看对象在运行过程中内存的变化。如图:
可以看到,我们的类的定义都存储在方法区内,当我们new一个对象时,就跟new数组一样,在堆(Heap)中申请了一块内存空间,而其中的成员方法则都被放到了方法区中,堆中的成员方法定义指向那块内存地址。当我们调用Phone对象的call方法时,他会通过地址找到call方法,然后将其压入栈(Stack)进行执行,执行完毕后立刻出栈,接着执行到sendMessage方法同理,执行完后也出栈。最后都执行完后,Main方法也出栈,整个程序运行结束。
总结
总的来说,主要是对java中各种内存在运行时的分配情况进行了一个简单的了解,之前都只是简单的会用,但对于底层还是理解的不够。