Java2java的内存划分程序计数器,本地方法栈,虚拟机栈,堆,方法区(?)
内存划分 | 作用 |
---|---|
堆内存 | 给对象提供存放空间 |
虚拟机栈 | 给方法提供运行空间 |
方法区 | 存放所有类相关的数据 |
本地方法栈 | 被native修饰的方法,java给本地调用的方法提供空间 |
类的方法以及其他属性都存在于本地方法区当中,当运行java时,栈就会给方法分配内存空间(入栈),运行结束后,栈会回收内存空间(出栈),所有引用数据类型(对象)都是存放在堆空间中,栈空间存放的是对象类型的内存地址,堆空间里对象的生命周期要比栈空间的数据长
实现swap交换函数
因为普通数据类型都存储在栈空间中,所以要通过数组,进行地址交换
public static void swap(int[] arr,int a,int b){ int tmp = arr[a]; arr[a] = arr[b]; arr[b] = tmp; }
代码运行流程(先进后出)
// 示例代码public static void main(String[] args){int[] arr = new int[10];}
- Java代码编译生成class文件
- class文件中的字节码数据被加载到Java内存的方法区中
- 栈内存的给main方法分配运行空间(入栈)
- 执行new向堆空间申请以快内存区域,用来建立一个长度为10,并且数组类型为 int 的数组,并赋予初值
- 数组的内存地址被赋予给了栈区域里的引用,通过地址访问堆内数组
- main 方法结束,释放栈空间(出栈)
- GC发现堆空间中数组没有被引用,从而释放堆空间
数组数组特点
数组具有下标(index),下标从0开始
数组在创建的时候,就需要定义其大小
数组通常用于存放相同数据类型的数据
静态初始化:在初始化数组的同时,就给数组完成赋值
动态初始化:在初始化数组的同时,不给数组元素赋值,多有数组的元素使用默认值
// 静态初始化(JVM会根据提供的数组数量,自动定义数组长度)int[] arr = {5,4,3,2,1,2,3,4,2,3,2,1,3,2};// 动态初始化int[] arr = new int[10];System.out.println(arr.length); // 查看数组长度
数组遍历
- for循环遍历(基础,不推荐)
int[] arr = new int[10];for(int i=0;i<arr.length;i++){ System.out.print(arr[i]+"\t");}
增强 for循环遍历(底层使用的是 itearor 迭代器)
增强for循环,只能用于数组遍历,不能用于做数组元素的修改。
int[] arr = new int[10];// 增强for循环中定义的变量,代表的不是下表,而是存放数组元素的临时变量for(int i:arr){ System.out.print(i+"\t");}
合并数组
// 合并数组public class Test{public static void main(String[] args){int[] a = {1,3,5,7,9}; int[] b = {2,3,4,5,6}; int[] target=new int[a.length + b.length]; System.arraycopy(a,0,target,0,a.length); System.arraycopy(b,0,target,a.length,b.length); for(int i :target){ System.out.print(i + "\t"); }}}
静态方法的基本使用(太简单了,咱就不写了?)
静态方法带有static修饰符
// 参数数量不同,顺序不同,类型不同,都可以实现方法重载public class Test{ public static void play(){ System.out.println("无参静态方法"); } public static void play(int tmp){ System.out.println("有参静态方法"); } public static void main(String[] args){ play(); play(1); }}// 输出无参静态方法有参静态方法
递归算法(同上?)