前两天,写程序时候,想传递一个数组名给一个函数,然后给数组new一下,并初始化数据,这样就使用非return,获得了一个初始化过对象,但是运行程序报“NullPointerException”。这是为什么???代码如下:
public class Test_object {
public int i;
public void star(){
int a[] = null;
int i;
init_a(a);
for(i=0; i<a.length; i++){
System.out.println(a[i]);
}
}
public void init_a(int[] a){
int i=0;
a = new int[5];
for(i=0;i<a.length;i++) a[i] = i++;
}
public static void main(String[] args) {
Test_object to = new Test_object();
to.star();
}
}
在开始讲解前,讲下预备知识!
1.java的函数调用的时候传递的是对象的引用。
2.变量存储在两块内存,变量名放在栈内存中,对象放在堆内存中。
3.对于对象,java传递参数时候,会将堆内存的地址传给函数。
4.数组在java中类似对象。
5.只声明不进行new的对象,不会在堆内存中开辟空间。
让我们回想下基本类型int、char等等的参数传递方式,是值传递。我们知道基本类型的变量存放在栈内存中,而没有存放在堆内存中。另外,在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。我们知道当值传递的时候,虚拟机在栈中开辟一块空间a,复制被传递的基本类型变量,然后将这个空间a交给目标函数。我们知道对象变量,也是存放在栈中的。那么我们猜想java中的引用传递应该是这样的过程:在栈中开辟一块空间b,然后将对象变量的值(也就是对象在对内存的地址)赋给b,这样就可以在函数中调用这个对象了,也就是所谓的引用传递。
总结:
1.值传递就是:新生成一个变量指向这个变量
2.此题的错因:这里我们没有给数组a在堆中开辟空间,那么a的栈内存中没有对象的地址值,所以此时退化成值传递