学习任务:

视频学习数组引用

动手测试程序理解一维数组的内存结构

动手测试方法传递数组引用

动手测试程序理解传值和传引用的区别

在方法中定义一个变量会在JVM栈内存开辟一个存储该变量的内存空间,在方法中定义一个数组会在JVM堆内存中开辟数组的内存空间,同时在栈内存中存储一个数组引用变量,它用来存储数组在堆内存的地址,见下图:

image-20200809114115151

在某个栈帧中定义一个字符数组a,在堆内存中开辟了存储数组元素的内存空间,同时在栈内存的a变量中存储a数组的引用,数组引用即是数组的内存地址,上图中,栈中的a变量存储了堆内存中a数组的起始地址0x0000 (0x0000是一个虚拟的内存地址,可看作是堆内存中该字符数组的第一个元素的地址)。

看下边的测试代码:

//导入类
import java.util.Random;
//或导入该类所属的包
import java.util.*;

/**
 * 	面向过程编程-数组-传引用
 * 
 * @author 攀博课堂(www.pbteach.com)
 *
 */
public class ArrayDemo3 {

	
	//测试数组的内存地址
	public static void ramAddress() {
		int[] c= new int[]{1,2,3,4,5,6};
		//将c的值赋值给e,此时c和e都指向了数组new int[]{1,2,3,4,5,6};
		int[] e = c;
		//输出数组e的地址
		System.out.println(e);
		//输出数组c的地址,c和e存储了同一个数组的地址,所以输出的内容一样
		System.out.println(c);
		//通过e给数组的元素赋值和通过c给数组元素复制效果一样,因为c和e存储了同一个数组的地址
		//通过e给数组的第一个元素赋值
		e[0]=100;
		//通过c获取数组的第一个元素的值
		System.out.println(c[0]);
		//通过c给数组的第二个元素赋值
		c[1]=200;
		//通过e获取数组的第二个元素的值
		System.out.println(e[1]);
	}
	
    public static void main(String[] args) {
    	ramAddress();
    	
    }
   
    
}

输出:

[I@15db9742
[I@15db9742
100
200

注意:[I@15db9742为内存地址,“[” 表示数组类型,“I”表示int整型,15db9742表示内存地址,不同的电脑其值不一样,这里要知道的是e 和a引用了堆内存中同一个数组的起始地址,所以System.out.println(e)和System.out.println(c)输出的内容一样。

下边是代码的内存结构图,int[] e和int[] c两个数组是同一个数组。

image-20200809144053346

下面通过练习实现方法之间传递数组引用 。

需求:随机产生10个整数存入数组并打印输出。

要求随机产生整数的功能和打印输出的功能在不同的方法中实现。

分析:

定义一个整型数组用来存储10个整数。

编写一个方法生成10个随机数存入数组。

生成随机数使用Random类来完成,例子如下:

import java.util.Random;

/**
 * 	面向过程编程-数组-练习1
 * 
 * @author 攀博课堂(www.pbteach.com)
 *
 */
public class ArrayDemo2 {

    public static void main(String[] args) {
    	Random random = new Random();
    	//随机产生一个100以内的整数三个数
    	System.out.println(random.nextInt(100));
    	for(int i=0;i<10;i++) {//随机产生10个100以内的整数三个数
        	System.out.println(random.nextInt(100));
    	}
    }
    
}

最后编写另一个方法遍历数组并打印输出。

内存的结构图如下:

image-20200809150931748

代码如下:

import java.util.Random;

/**
 * 	面向过程编程-数组-练习1
 * 
 * @author 攀博课堂(www.pbteach.com)
 *
 */
public class ArrayDemo2 {

    public static void main(String[] args) {
    	//定义一个int数组,长度为10,用于存储10个随机数
    	int[] datas = new int[10];
    	//生成随机数,将数组的引用地址传入setArrays
    	setArrays(datas);
    	//输出随机数,将数组的引用地址传入getArrays
    	getArrays(datas);
    }
    /**
     * 	随机产生10个100以内的整数并存入数组
     * @param a 数组引用
     */
    public static void setArrays(int[] a) {
    	//定义生成随机数对象
    	Random random = new Random();
    	for(int i=0;i<a.length;i++) {//随机产生10个100以内的整数并存入数组
    		a[i]=random.nextInt(100);
    	}
    }
    /**
     * 	遍历数组并输出数组元素
     * @param b 数组引用
     */
    public static void getArrays(int[] b) {
    	//遍历数组并输出数组元素
    	for(int i=0;i<b.length;i++) {
    		System.out.println(b[i]);
    	}
    }
    
}

通过本次练习我们学会了数组引用通过方法之间进行传递。

理解方法之间传值和传引用的区别:

1)传引用

“传引用” 传递的是内存地址,将数组名作为参数是传引用,将引用传入方法,方法内部是可以修改外部的数据的。

如:上例中在main方法中定义datas数组,虽然是在main方法栈中定义的数组,但是将数组的引用传入setArrays方法,在setArrays方法内是可以操作main方法中定义的datas数组的元素的。

2)传值

“传值” 传递的是具体的数值,普通的int、long等基本数据类型作为方法参数时为传值,一个方法将变量值传入另一个方法,两个方法修改变量的值互不影响。下图是一个传值的例子:

image-20200809152501409

测试代码如下:

import java.util.Random;

/**
 * 	面向过程编程-数组-练习1
 * 
 * @author 攀博课堂(www.pbteach.com)
 *
 */
public class ArrayDemo2 {
	public static void main(String[] args) {
    	
    	//测试传值
    	int a = 100;
    	setData(a);
    	System.out.println("a="+a);
    }
    /**
     * 测试传值
     *
     */
    public static void setData(int b) {
    	b = 50;
    	System.out.println("b="+b);
    }
    
}

输出:

b=50
a=100
提问-攀博课堂
我要提问 不会就问,有效沟通
关注公众号,加入微信群交流提问。 攀博课堂官方公众号
问答列表,查看本知识点所有问题