java 参数传递_Java中的参数传递

为了便于理解,会将参数传递分为按值传递和按引用传递。按值传递是传递的值的拷贝,按引用传递传递的是引用的地址值,所以有“在java里参数传递都是按值传递”、“引用也是按值传递的”这些说法。

基本数据类型作为参数传递

基本数据类型作为参数传递时都是传递值的拷贝。 指的是方法调用中,传递的是值的拷贝,无论怎么改变这个拷贝,原值是不会改变的。

也即是说实参把它的值传递给形参,对形参的改变不会影响实参的值。

public class Test {

public static void main(String[] args) {

Test test1 = new Test();

int i = 5;

System.out.println("调用前的i=" + i);

test1.testPassParameter(i);

//传递后,testPassParameter方法中对形参i的改变不会影响这里的i

System.out.println("调用后的i=" + i);

}

public void testPassParameter(int i) {

i = 10;//这里只是对形参的改变

System.out.println("tpp方法中的i=" + i);

}

}

输出结果:

调用前的i=5

tpp方法中的i=10

调用后的i=5

对象作为参数传递

对象作为参数传递时,在方法内改变对象的值,有时原对象跟着改变,而有时又没有改变。就会让人对“传值”和“传引用”产生疑惑。

先看看两种情况的例子。

public class Test {

public static void main(String[] args) {

StringBuffer s1 = new StringBuffer("hello");

StringBuffer s2 = new StringBuffer("hello");

changeStringBuffer(s1, s2);

System.out.println("s1=" + s1);

System.out.println("s2=" + s2);

}

public static void changeStringBuffer(StringBuffer ss1, StringBuffer ss2) {

ss1.append("world");

ss2 = ss1;

}

}

输出结果:

s1=helloworld

s2=hello

分析如下:

//(1)s1,s2指向字符串的地址不同,假设为地址1,地址2

StringBuffer s1 = new StringBuffer("hello");

StringBuffer s2 = new StringBuffer("hello");

c63596a87eee?from=groupmessage

image

//(2)调用changeStringBuffer方法

changeStringBuffer(s1, s2);

//调用后会将s1,s2的地址(地址1,地址2)传给ss1,ss2,即现在ss1也指向地址1,ss2也指向地址2

c63596a87eee?from=groupmessage

image

//(3)ss1所指向字符串的值变为helloworld,调用者s1的值相应变化。

ss1.append("world");

//ss2将指向ss1指向的地址(地址1),但此时s2依旧指向地址2,s2的值在调用前后不变。

ss2 = ss1;

c63596a87eee?from=groupmessage

image

所以,s1的输出为helloworld,s2的输出结果为hello。

(注意,这里为了区分,s1,s2和ss1,ss2用了不同的名称,但有时候形参与实参的名字相同,其实两者变量是完全不同的,一个是main方法中的变量,一个是changeStringBuffer()中的变量。)

可以看出,在java中对象作为参数传递时,传递的是引用的地址,是把对象在内存中的地址拷贝了一份传给了参数。

拓展:

基本数据类型的包装类型在传递参数时其实也是“按引用传递的”,只是因为包装类型变量都是不可变量,容易误解。

String是final类型,是个特殊的类,对它的一些操作符是重载的。比如:

String str = "hello";//等价于String str=new String("hello");

String str = "hello";

str = str + "world";//等价于str = new String(new StringBuffer(str).append("world"));

从以上分析,现在可以更易理解下面的代码:

public class Test {

public static void fun(String str, char ch[]) {

str = "world";

ch[0] = 'd';

}

public static void main(String[] args) {

String str = new String("hello");

char[] ch = {'a', 'b', 'c'};

fun(str, ch);

System.out.println(str);

System.out.println(ch);

}

}

输出结果

hello

dbc

方法调用时,名称相同的实参和形参并不一样,一个是main()中的str,指向存放"hello"的内存地址。一个是fun()中的str,str="world",相当于new String("world")。String是final类型,将在堆中重新分配一个内存空间存放"world"。ch[0]='d',对象的内容发生改变。

c63596a87eee?from=groupmessage

image

所以main()中str变量存放的对象内容依然是"hello"。ch从"abc"变为"dbc"。

参考:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值