Java内存图

public class Person {
 
	public int age;
	public String name;
	
	public static int flag;
	
	public void m1() {
		System.out.println("m1正常");
	}
	public static void m2() {
		System.out.println("m2正常");
	}
	@Override
	public String toString() {
		return "Person [age=" + age + ", name=" + name + " flag = "+flag+"]";
	}
 
public class Test {
 
	public static void main(String[] args) {
		Person x1 = new Person();
		x1.age = 20;
		x1.name = "张三";
		x1.flag = 1;
		
		Person x2 = new Person();
		x2.age = 22;
		x2.name="李四";
		x2.flag = 2;
 
		change1(x1,x2);
		
		change2(x1,x2);
		System.out.println(x1);
		System.out.println(x2);
	}
	
	public static void change1(Person a,Person b) {
		Person temp = a;
		a=b;
		b=temp;
	}
	
	public static void change2(Person a,Person b) {
		int temp_age = a.age;
		String temp_name = a.name;
		
		a.age = b.age;
		a.name = b.name;
		
		b.age = temp_age;
		b.name = temp_name;
	}

以上代码在内存中的运行逻辑是什么样子的呢?

要想知道这个知识,我们需要先了解一下Java内存区域的分布和作用

1.方法区,方法区又分为类常量池和静态常量池

              类常量池对当前的类做一个简单的概括,并未真正开辟空间

              静态常量池对程序中静态的分程序、类型等进行备份

2.栈区(先进后出),方法区的方法要执行需要入栈,且栈区中可能不止一个栈

              该区域用于辅助方法执行

3.堆区(只开劈非静态类型数据的空间),堆区中有一个区域叫做字符串常量池

              用于辅助方法、变量等的存储

4.程序计数器

5.本地方法栈

了解这些后,我们就可以开始研究代码了

1,Person类和Test类会进入类常量池

2,其中的静态变量会拷贝一份存入静态常量池

3,main方法入栈,并在堆区开辟对应空间存储相应数据,其中字符串型存放在字符串常量池

4,执行main方法里的change1(),此时change1()方法入栈,a和b分别存储x1和x2的数值

5,执行方法后a和b的值互换,但并没有影响堆中和main方法中的数据,change1()执行完后出栈

Person temp = a;
a=b;
b=temp;

可见x1和x2没有任何变化

6,change2()方法入栈

开始执行

a.age = b.age;
a.name = b.name;
b.age = temp_age;
b.name = temp_name;

最后change2()出栈,可见堆中数据被改变了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值