java传参数的时候是值传递还是引用传递是个很有意思的问题,
一些有几年工作经验的人也会因此而困惑,
面试的时候更是经常有这样的问题,
今天我整理了一下自己对于这个问题的理解,
希望对一些还没弄清楚此问题的人有所帮助
1、基本类型当参数传递的情况
输入的结果是10。
原因是在进入changei(i)的时候,
会把i的值复制一份传递给方法,
方法里面的修改已经和原来i的值无关了。
2、类对象当做参数传递的情况
输出的结果是20,
进入another(a)方法的时候,
把a对象的引用的值当作参数传递给another方法,
another方法里面通过引用的值去修改的实际上还是a对象的内存区域,
所以方法结束后打印a.i的值是20。
3、对于类对象传参扩展一下
这个输出的结果是什么呢?
答案是:
10
20
这个有点意思了吧
可以这样理解;
在调用another(a)的时候,
a.i的值还是30,
这个时候把a对象的引用复制一份,
把这个复制品传递给another方法,记住是传递的是a对象的引用的复制品,
another方法里面第一步修改a.i=20的时候,
引用的复制品指向的还是a原始的内存,
此时a.i的已经从30变成20了。
然后new了一个新对象,把a指向新的对象,
实际上是把a对象的引用的复制品指向了新对象,
而a对象的实际引用没有改变。
然后打印a.i,是10。
方法结束后打印a.i是20。
说到这里你理解了么
4、对于String类型作参数传递的问题
输出结果是:
hello
String虽然不是基本类型,
但是作参数传递的情况和基本类型作参数传递类似,
因为String类的内部实现是char[],
可以把String理解为char类型的包装类(类似于int和Integer一样)
具体可以参考这篇文章:
http://freej.blog.51cto.com/235241/168676
ps:
有些文章上说java只有值传递,没有引用传递,
可以这样理解,当类对象作参数传递的时候传递的是引用或地址的值,
从这个角度看,确实,java只有值传递。
一些有几年工作经验的人也会因此而困惑,
面试的时候更是经常有这样的问题,
今天我整理了一下自己对于这个问题的理解,
希望对一些还没弄清楚此问题的人有所帮助
1、基本类型当参数传递的情况
- /**
- * 基本数据类型
- */
- public static void main(String[] args) {
- int i=10;
- changei(i);
- System.out.println(i);
- }
- public static void changei(int x){
- x=20;
- }
/**
* 基本数据类型
*/
public static void main(String[] args) {
int i=10;
changei(i);
System.out.println(i);
}
public static void changei(int x){
x=20;
}
输入的结果是10。
原因是在进入changei(i)的时候,
会把i的值复制一份传递给方法,
方法里面的修改已经和原来i的值无关了。
2、类对象当做参数传递的情况
- public class BValue {
- public int i=10;
- public static void main(String...args){
- BValue a=new BValue();
- another(a);
- System.out.println(a.i);
- }
- public static void another(BValue a){
- a.i=20;
- }
- }
public class BValue {
public int i=10;
public static void main(String...args){
BValue a=new BValue();
another(a);
System.out.println(a.i);
}
public static void another(BValue a){
a.i=20;
}
}
输出的结果是20,
进入another(a)方法的时候,
把a对象的引用的值当作参数传递给another方法,
another方法里面通过引用的值去修改的实际上还是a对象的内存区域,
所以方法结束后打印a.i的值是20。
3、对于类对象传参扩展一下
- public class AValue {
- public int i=10;
- public static void main(String...args){
- AValue a=new AValue();
- a.i=30;
- another(a);
- System.out.println(a.i);
- }
- public static void another(AValue a){
- a.i=20;
- AValue b=new AValue();
- a=b;
- System.out.println(a.i);
- }
- }
public class AValue {
public int i=10;
public static void main(String...args){
AValue a=new AValue();
a.i=30;
another(a);
System.out.println(a.i);
}
public static void another(AValue a){
a.i=20;
AValue b=new AValue();
a=b;
System.out.println(a.i);
}
}
这个输出的结果是什么呢?
答案是:
10
20
这个有点意思了吧
![](https://i-blog.csdnimg.cn/blog_migrate/0f4d77d2428237de8faeb86d8b323509.gif)
可以这样理解;
在调用another(a)的时候,
a.i的值还是30,
这个时候把a对象的引用复制一份,
把这个复制品传递给another方法,记住是传递的是a对象的引用的复制品,
another方法里面第一步修改a.i=20的时候,
引用的复制品指向的还是a原始的内存,
此时a.i的已经从30变成20了。
然后new了一个新对象,把a指向新的对象,
实际上是把a对象的引用的复制品指向了新对象,
而a对象的实际引用没有改变。
然后打印a.i,是10。
方法结束后打印a.i是20。
说到这里你理解了么
4、对于String类型作参数传递的问题
- public class TestString {
- public static void main(String[] args) {
- String str="hello";
- change(str);
- System.out.println(str);
- }
- public static void change(String s){
- s="world";
- }
- }
public class TestString {
public static void main(String[] args) {
String str="hello";
change(str);
System.out.println(str);
}
public static void change(String s){
s="world";
}
}
输出结果是:
hello
String虽然不是基本类型,
但是作参数传递的情况和基本类型作参数传递类似,
因为String类的内部实现是char[],
可以把String理解为char类型的包装类(类似于int和Integer一样)
具体可以参考这篇文章:
http://freej.blog.51cto.com/235241/168676
ps:
有些文章上说java只有值传递,没有引用传递,
可以这样理解,当类对象作参数传递的时候传递的是引用或地址的值,
从这个角度看,确实,java只有值传递。