1、基本类型或基本类型的包装类以及String是值传递,引用类型是引用传递。
2、Java中只有值传递。
关于这个问题应该是存在争议的。根据测试出来的结果和我们自己的经验,以及口口相传或是上学时老师讲的,我们认为是第一种。但第二种说法的呼声也很高,渐渐地我们也认为第2中才是对的。那么下面我们就来分析一下这个问题。
在谈这个问题之前我们先了解值传递和引用传递的概念及现象。我还记得,值传递和引用传递这些概念是大学里学Java的时候老师教给我的,它们的概念是什么呢?老师是通过例子来讲解的,大概是这样的。
值传递例子1:
1public static void main(String[] args){2 TestJavaParamPass() tjpp = new TestJavaParamPass();
3 int num = 10;
4 tjpp.change(num);
5 System.out.println("num in main():"+i);
6}
7public void change(int param){
8 param = 20;
9 System.out.println("param in change():"+param);
10}
控制台输出:
1param in change():102num in main():20
mian()方法中的int变量num传递给change()方法,change()方法接收到后将值改变为20。通过看控制台输出,main()方法中的num变量的值没有改变。
结论:基本类型是值传递。
引用传递例子2:
1public static void main(String[] args){2 TestJavaParamPass() tjpp = new TestJavaParamPass();
3 User user = new User();
4 user.setName("Jerry");
5 tjpp.change(user);
6 System.out.println("user in mian():"+user);
7}
8public void change(User param){
9 param.setName("Tom");
10 System.out.println("param in change():"+param);
11}
控制台输出:
1param in change():User(name=Tom}2user in mian():User(name=Tom}
main()方法中的user变量传递给change()方法,change()方法改变了其name属性值。通过看控制台输出,main()方法中的user变量的name属性值发生改变。
结论:引用类型是引用传递。
特殊的值传递例子3:
1public static void main(String[] args){2 TestJavaParamPass() tjpp = new TestJavaParamPass();
3 String name = "Jerry";
4 tjpp.change(name);
5 System.out.println("name in main():"+i);
6}
7public void change(String param){
8 param = "Tom";
9 System.out.println("param in change():"+param);
10}
控制台输出:
1param in change():Tom2name in mian():Jerry
String也是引用类型的数据类型,为什么值没改变?因为在change()方法里param = "Tom";相当于param = new String("Tom");就相当于param被重新赋值指向了另外一个对象。所以,其实String类型传的是引用,只不过被重新赋值指向了别的对象了,没有修改原对象。即,String本质上还是引用传递,表像上是值传递。
结论:基本类型是值传递,引用类型是引用传递,String是特殊的值传递。
这个结论也是网络上流传的比较多的,可能大部分程序员的认知都是这样的。至于值传递和引用传递的概念,接下来便可根据上面的例子和结论推断出来,以及解释为什么大多数程序员都将String理解为是特殊的值传递。
概念提取与其叫概念提取好不如叫结论总结呢。
值传递:基本类型的变量在被传递给方法时,传递的是该变量的值(即复制自己的值传递给方法)。
引用传递:引用类型的变量在被传递给方法时, 传递的是该变量的引用(即自己所指向的内存地址)。