1.2 java之入门(内存分析)

思考为什么需要堆和栈
栈是运行时的单位,而堆是存储的单位,栈解决程序的运行问题,堆解决数据存储的问题。

一个线程对应一个线程栈,栈是运行单位,里面存储的信息都是跟当前线程相关的信息,包括局部变量、程序运行状态、方法返回值等,而堆只负责存储对象信息,堆被所有线程共享,堆就是一块共享的内存。

为什么要把堆和栈区分出来呢?栈中不是也可以存储数据吗?

第一,从软件设计的角度看,栈代表了处理逻辑,而堆代表了数据。这样分开,使得处理逻辑更为清晰。分而治之的思想。这种隔离、模块化的思想在软件设计的方方面面都有体现。

第二,堆与栈的分离,使得堆中的内容可以被多个栈共享(也可以理解为多个线程访问同一个对象)。这种共享的收益是很多的。一方面这种共享提供了一种有效的数据交互方式(如:共享内存),另一方面,堆中的共享常量和缓存可以被所有栈访问,节省了空间。

第三,栈因为运行时的需要,比如保存系统运行的上下文,需要进行地址段的划分。由于栈只能向上增长,因此就会限制住栈存储内容的能力。而堆不同,堆中的对象是可以根据需要动态增长的,因此栈和堆的拆分,使得动态增长成为可能,相应栈中只需记录堆中的一个地址即可。

1.java程序在内存中运行.

2.内存划分:

栈:存放局部变量和栈帧(main()在栈帧中运行).效率最高.
堆:所有new出来的东西存放在堆中.和成员属性,效率比栈低点.
方法区:存放.class文件,静态区(存放静态变量),常量池(存放常量).效率最低.
	注意:常量池中数据不可重量.

3.一个对象内存分析:
在这里插入图片描述

eg:public class Test1 {
public static void main(String[] args) {
	//创建对象
	Student stu1=new Student();
	
	//用对象调用方法给属性赋值
	stu1.setSname("张三");
	stu1.setSage(11);
	
	System.out.println("学生姓名:"+stu1.getSname()+",年龄:"+stu1.getSage());
}
}

4.多个对象的内存分析
在这里插入图片描述

public class Test2 {

public static void main(String[] args) {
	//创建对象
	Student stu1=new Student();
	Student stu2=new Student();
	
	//用对象调用方法给属性赋值
	stu1.setSname("张三");
	stu1.setSage(11);
	
	stu2.setSname("李四");
	stu2.setSage(18);
	
	System.out.println("学生姓名:"+stu1.getSname()+",年龄:"+stu1.getSage());
	System.out.println("学生姓名:"+stu2.getSname()+",年龄:"+stu2.getSage());
}
}

5.方法传参
在这里插入图片描述

5.1:值传递:方法的形参是基本数据类型叫值传递,值传递传的是实参变量值,所以在方法中对值作了更改,在方法中这些值变了,方法执行完后,实参变量的值不变.
	 
	eg:public class Test3 {
public static void main(String[] args) {
	//声明两个变量并赋值
	int a=8;
	int b=10;
	System.out.println("交换前两个数为:a="+a+",b="+b);//8,10
	
	//创建对象,用对象调用方法交换两个数
	Change c=new Change();
	c.changeNum(a, b);
	
	System.out.println("交换后两个数为:a="+a+",b="+b);//8,10
}
}

5.2:引用传递:方法形参是引用数据类型叫引用传递.引用 传递传的是实参变量的内存地 址,在方法对内存地址中值作了更改,方法中值就改了,方法执行完后实参变量的值改变了.
在这里插入图片描述

    eg:public static void main(String[] args) {
	//创建对象
	Student stu2=new Student();
	stu2.setSname("王五");
	stu2.setSage(100);
	System.out.println("改变前对象的姓名:"+stu2.getSname()+",年龄:"+stu2.getSage());//王五,100
	
	//创建对象调用方法改变对象的属性值
	Change c=new Change();
	c.changeStu(stu2);
	
	System.out.println("改变后对象的姓名:"+stu2.getSname()+",年龄:"+stu2.getSage());//江展华,30
}

6.数组的内存分析
在这里插入图片描述

public static void main(String[] args) {
	//声明一维数组
	int[] nums=new int[3];
	//给一维数组每个空间赋值
	nums[0]=59;
	nums[1]=49;
	nums[2]=99;
	System.out.println("一维数组:"+Arrays.toString(nums));
	
	//声明二维数组
	int[][] arrs=new int[2][2];
	//给二维数组的每个空间一维数组每个空间赋值
	arrs[0][0]=11;
	arrs[0][1]=12;
	
	arrs[1][0]=21;
	arrs[1][1]=22;
	System.out.println("二维数组:");
	for (int[] a : arrs) {
		System.out.println(Arrays.toString(a));
	}
	
	//声明对象数组,本质一维数组,数组的每个空间存的是一个对象
	//对象数组整体遵循数组使用原则,数组中每个空间是一个对象遵循对象使用原则
	Student[] stus=new Student[2];
	//给对象数组每个空间赋值,数组名[索引]相当于对象名
	stus[0]=new Student();
	stus[0].setSname("小明");
	stus[0].setSage(18);
	
	stus[1]=new Student();
	stus[1].setSname("小红");
	stus[1].setSage(28);
	System.out.println("对象数组:"+Arrays.toString(stus));
}

7.(扩展)对象数组:本质是一维数组,只是数组的每个空间存的对象的内存地址.

注意:对象数组整体上遵循数组使用原则;
	对象数组的每个空间是一个对象要遵循对象使用原则;
	对象数组的值实际存在对象的属性中.
	eg:public static void main(String[] args) {
	//声明int数组
	int[] nums1=new int[3];
	//给int数组赋值
	nums1[0]=11;
	nums1[1]=12;
	nums1[2]=13;
	
	System.out.println("int数组nums1:"+Arrays.toString(nums1));
	
	//声明对象数组
	Student[] stus1=new Student[2];
	//给对象数组赋值
	stus1[0]=new Student();
	//用数组每个空间(即对象),用对象调出属性存值
	stus1[0].setSname("aa");
	stus1[0].setSage(18);
	
	stus1[1]=new Student();
	//用数组每个空间(即对象),用对象调出属性存值
	stus1[1].setSname("bb");
	stus1[1].setSage(38);
	
	System.out.println("对象数组stus1:"+Arrays.toString(stus1));
	
	//声明int数组的同时赋值
	int[] nums2= {66,88,99};
	System.out.println("int数组nums2:"+Arrays.toString(nums2));
	
	//声明对象数组的同时赋值
	Student[] stus2= {new Student("cc", 17),new Student("dd", 18)};
	System.out.println("对象数组stus2:"+Arrays.toString(stus2));
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值