行参和实参
行参:方法在被调用的时候需要传递进来的参数。如function(int a)中的参数a,只有在方法被调用的时候a才有意义。
实参:方法在被调用时,实计被传入的值。在方法被调用前已经被初始化。
JAVA中基本类型和引用类型
基本类型:byte、short、int、long、float、double、char、boolean
引用类型:类,数组等
值传递和引用传递
把实参的值赋值给行参,那么对行参的修改不会影响实参的值
把实参的地址传递给行参,行参和实参是同一个对象,只是名字不同,对行参的修改会影响实参的值。
下面我们先来看一看基本类型的操作:
public static void main(String[] args) {
int a=1;
System.out.println("a="+a);
func(a);
System.out.println("a="+a);
}
private static void func(int a){
a=10;
}
输出结果为:
a=1
a=1
通过上面的结果可以看出,对于基本类型的数据,在实参传入形参时,都是值传递,而不是内容本身。
下面我们来看看引用类型的操作:
public static void main(String[] args) {
P p=new P();
p.setName("芃兮贝贝");
System.out.println(p.getName());
func(p);
System.out.println(p.getName());
}
private static void func(P p){
p.setName("贝贝");
}
输出结果为:
芃兮贝贝
贝贝
通过上面的结果可以看出在方法中对引用类型的行参进行修改,最后实参的值也被修改了。那么是不是可以得出结论:
java中基本类型是值传递,引用类型是引用传递呢?
接下来我们再看一个例子:
public static void main(String[] args) {
P p=new P();
p.setName("芃兮贝贝");
System.out.println(p.getName());
func(p);
System.out.println(p.getName());
}
private static void func(P p){
p=new P();
p.setName("贝贝");
}
这段代码比上面的代码是方法func中增加了一行: p=new P();
我们来看看结果:
芃兮贝贝
芃兮贝贝
奇怪,为什么这次实参的值没被修改呢?
其实,熟悉JVM的朋友们都知道,在JVM中对象是存储在堆内存中的,而且堆内存是共享的,而变量p的值只是一个堆内存的地址,当调用func时,把实参的值传给行参时,是传的一个内存地址,这个时候实参和行参是指向的同一个地址。这个时候如果对行参的修改自然实参也是读到修改后的内容。但是如果行参重新new了一个对象,这个时候JVM会在堆中重新创建内存块来存这个对象。这个时候行参和实参就是两个不同的内存地址了。现在对行参的修改自然是不会影响实参。