Java数组及内存图解

  • 今天整理了Java函数,数组,内存加载使用的问题,在这之前我先把昨天剩下的for语句写下来。

for语句

Java for语句基础

  • \n 回车
    \t 制表符
    \b 退格
    \r 按下回车键

  • windows系统中回车符其实是由两个符号组成 \r \n
    linux 回车符只是 \n

    1
    System.out.println("\"hello world\"");
  • 上段代码最后输出结果是 “hello world” 有引号的,\会将他下一个字符转义

break 跳出

  • 作用范围:swich语句 or 循环语句

  • 当break语句单独存在时,下面不要定义其他语句,因为执行不到

    1
    2
    3
    4
    5
    6
    A:for(int x=0; x<3; x++){
    B:for(int y=0; y<6; y++){
    System.out.println(x);
    break A;
    }
    }
  • 大家观察一下上面的语句,这就是break的特殊用法,可以将for循环定义名字,break选择性的使用。

continue 继续

  • 作用范围:循环结构

  • 结束本次循环,继续下次循环

  • continue语句单独存在时,下面不要定义其他语句,因为执行不到

1
2
3
4
5
for(int x=0; x<9; x++){
if(x%2 == 0)
continue;
System.out.println(x);
}

函数

  • 函数:定义在类中具有特定功能的一段小程序,也称方法。

定义及格式

  • 定义函数格式:
1
2
3
4
修饰符 返回值类型 函数(参数类型 形参1, ... ... ,){
执行语句;
return 返回值;
}
  • 无具体返回值时,返回值类型用void,return可以忽略不写

功能

  • 1 定义函数可将代码封装

  • 2 便于对该功能复用

  • 3 函数只有被调用才能执行

两个明确

  • 1 函数功能结果是什么?
  • 2 实现过程中是否需要未知内容参与运算?

函数重载

  • 1 同一个类中的同名函数
  • 2 参数个数不同或者是参数类型不同
  • 3 函数重载与返回值无关
  • 4 Java严谨性语言,如果函数出现调用不确定性,会编译失败(比如int返回值却是double参数类型)

数组

Java数组基础

内存

  • 内存的划分
    • 寄存器
    • 本地方法区
    • 方法区
    • 栈内存
    • 堆内存

栈内存

  • 存储的都是局部变量,变量所属作用域一旦结束,该变量就自动释放

堆内存

  • 储存数组和对象(数组就是对象),new 建立的都在堆上
  • 特点:
    1. 每个实体都有首地址值
    2. 堆内存中每个变量都有默认内存初始值,根据类型不同而不同
      (int -> 0,double -> 0.0,float -> 0.0f,boolean -> false,char -> ‘\u0000’)
    3. 垃圾回收机制

数组运行内存图解

一维数组
  • 接下来我就通过这段代码来演示运行时的内存变化

    1
    2
    3
    4
    5
    6
    7
    int[] x = new int[3];
    int[] y = new int[3];
    x[0] = 9;
    y[0] = 34;
    x = y;
    System.out.println(x[0]);
    y = null;
  • 栈中运行main然后存入x数组名,堆中分配地址(16进制),找到这个地址,开辟数组大小的空间,并给予其初始值。然后将数组地址传回栈中。

  • 给x[0],y[0]赋值时,就是直接在堆内存中更改数据
  • x=y 语句的执行实质上就是将y的地址赋给x,下次再调用x的时候,即直接找到y的地址
  • 当y = null; 就是将堆内存 和栈内存的指向关系删去,

    1
    2
    int[] x = new int[3];
    System.out.println(x[]);
  • 如果直接运行上段代码,所得到的结果是一串字符

  • [I@1540e19d (我运行后的值)

  • [: 代表数组
    I:int 实体类型
    1540e19d:16进制的哈希值(地址)

二维数组
  • 直接来是二维数组的图解
    1
    2
    3
    int[][] arr = new int[3][2];
    arr[1][1] = 89;
    arr[2][2] = 89; //error

  • 大家看下图,以上图为例,所谓二维数组就是栈内存中存下指向堆内存的地址,这个地址是大小为3的数组,初始值为空,然后再创建3个小的数组,每个小数组还有一个地址,将这些地址对应存到之前大小为3的数组中。

    1
    2
    3
    4
    int[][] arr = new int[3][2];
    System.out.println(arr);
    System.out.println(arr[0]);
    System.out.println(arr[0][0]);
  • 输出的结果

    1
    2
    3
    [[I@1540e19d
    [I@677327b6
    0
  • 再来看看另一种定义下的情况

    1
    2
    3
    4
    int[][] arr = new int[3][];
    System.out.println(arr);
    System.out.println(arr[0]);
    System.out.println(arr[0][0]);
  • 结果如下

    1
    2
    3
    [[I@1540e19d
    null
    Exception in thread "main" java.lang.NullPointerException