Java方法的值传递机制

栈:
描述Java方法执行的内存模型,每个方法被执行的时候都会同时创建一个栈帧用于存储局部变量、操作栈、动态链接、方法出口等信息。
每一个方法,创建一个栈帧,栈帧存放了当前就方法的数据信息(局部变量),当方法调用完毕,该方法的栈帧就被销毁。


堆:
被所有线程共享的一块内存区域,在虚拟机启动时创建。所有的对象实例以及数组都要在堆上分配,使用new关键字,就表示在堆中开辟一块新的存储空间


方法区:
线程共享的内存区域,存储已被虚拟机加载的类信息、常量池、static变量等。

———————————————————————————————————————————————————————————————————————


Java值传递机制——基本数据类型

package com.mipo.javase.reference;
/**
 * 方法参数的值传递机制之基本数据类型 
 * 结论:
 * 如果参数类型是基本数据类型,那么传过来的就是这个参数的一个副本,也就是这个原始参数的值。
 * 如果在函数中改变了副本的值,原始的值不会改变
 * @author Administrator
 *
 */
public class ParameterDemo1 {
	//每个方法执行时,都会创建一个栈帧,栈帧存放了当前方法的数据信息(局部变量、方法参数)
	//在栈空间中创建main方法的栈帧
	public static void main(String[] args) {
		//main方法的栈帧中开辟一块内存空间,存放 x=10
		int x = 10;
		//打印结果10
		System.out.println("main方法前:"+x);
		//在栈空间中创建change方法的栈帧,此时该栈帧位于栈顶,谁在栈顶就执行谁
		//把x的值拷贝一份,再传递给change()方法的x变量(传递仅仅是数值10)
		change(x);
		//当change()方法调用完毕后,它就会出栈;main方法又回到栈顶,谁在栈顶就执行谁
		//在main方法的栈帧里,x=10
		//打印结果10
		System.out.println("main方法后:"+x);
	}
	
	static void change(int x) {
		//change()方法的栈帧中开辟一块内存空间,存放形参x
		//打印结果10
		System.out.println("change方法前:"+x);
		//把50赋值给了change()方法中的变量x
		x = 50;
		//打印结果50
		System.out.println("change方法后:"+x);
	}

}
从JVM内存角度分析

Java方法的值传递机制_第1张图片

Java值传递机制——引用数据类型

package com.mipo.javase.reference;
/**
 * 方法参数的值传递机制之引用数据类型
 * 结论:
 * 如果参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址值。
 * 如果在函数中没有改变这个副本的地址,而是改变了地址中的内容,那么在函数内的改变会影响到传入的参数。
 * 如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,此时传入的参数还是指向原来的地址,所以不会改变参数的值。
 * @author Administrator
 *
 */
public class ParameterDemo2 {
	//每个方法执行时,都会创建一个栈帧,栈帧存放了当前方法的数据信息(局部变量、方法参数)
	//在栈空间中创建main方法的栈帧
	public static void main(String[] args) {
		//栈区的arr引用的是堆空间的new对象
		int[] arr = new int[]{10,99,101} ;
		//打印结果10,99,101
		System.out.println("main方法前:"+arr[0]+","+arr[1]+","+arr[2]);
		//在栈空间中创建change方法的栈帧,此时该栈帧位于栈顶,谁在栈顶就执行谁
		//把main方法中的arr所引用的地址值:0x342f(十六进制表示)复制一份,把复制之后的副本传递给change方法的arr变量
		change(arr);
		//当change()方法调用完毕后,它就会出栈;main方法又回到栈顶,谁在栈顶就执行谁
		//由于main()方法和change()方法操作的是堆空间的同一地址,此时arr的值改了
		//打印结果55,99,101
		System.out.println("main方法后:"+arr[0]+","+arr[1]+","+arr[2]);

	}
	
	static void change(int[] arr) {
		//change()方法的栈帧中开辟一块内存空间,存放形参x
		//打印结果10,99,101
		System.out.println("change方法前:"+arr[0]+","+arr[1]+","+arr[2]);
		//把堆空间的arr[0]更改为55
		arr[0] = 55;
		//打印结果55,99,101
		System.out.println("change方法后:"+arr[0]+","+arr[1]+","+arr[2]);
	}

}

从JVM内存角度分析

Java方法的值传递机制_第2张图片

package com.mipo.javase.reference;
/**
 * 方法参数的值传递机制之引用数据类型
 * 结论:
 * 如果参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址值。
 * 如果在函数中没有改变这个副本的地址,而是改变了地址中的内容,那么在函数内的改变会影响到传入的参数。
 * 如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,此时传入的参数还是指向原来的地址,所以不会改变参数的值。
 * @author Administrator
 *
 */
public class ParameterDemo2 {
	//每个方法执行时,都会创建一个栈帧,栈帧存放了当前方法的数据信息(局部变量、方法参数)
	//在栈空间中创建main方法的栈帧
	public static void main(String[] args) {
		//栈区的arr引用的是堆空间的new对象
		int[] arr = new int[]{10,99,101} ;
		//打印结果10,99,101
		System.out.println("main方法前:"+arr[0]+","+arr[1]+","+arr[2]);
		//在栈空间中创建change方法的栈帧,此时该栈帧位于栈顶,谁在栈顶就执行谁
		//把main方法中的arr所引用的地址值:0x342f(十六进制表示)复制一份,把复制之后的副本传递给change方法的arr变量
		change(arr);
		//当change()方法调用完毕后,它就会出栈;main方法又回到栈顶,谁在栈顶就执行谁
		//由于main()方法和change()方法操作的是堆空间的同一地址,此时arr的值改了
		//打印结果10,99,101
		System.out.println("main方法后:"+arr[0]+","+arr[1]+","+arr[2]);

	}
	
	static void change(int[] arr) {
		//change()方法的栈帧中开辟一块内存空间,存放形参x
		//在堆中又创建一个对象arr,把main()方法中传递过来的地址值改为新的地址值
		arr = new int[]{20,99,101};
		//打印结果20,99,101
		System.out.println("change方法前:"+arr[0]+","+arr[1]+","+arr[2]);
		//把堆空间的arr[0]更改为55
		arr[0] = 55;
		//打印结果55,99,101
		System.out.println("change方法后:"+arr[0]+","+arr[1]+","+arr[2]);
	}

}








你可能感兴趣的:(Java,Java值传递机制,基本数据类型,引用数据类型)