之所以写这篇文章是因为前些天写了一篇探讨了网上关于Java只有值传递的说法,当时写这篇文章的缘由是因为之前看的文章讲解的Java只有值传递,讲的不是让我很明白,没有拿出比较专业的解释或定义,没有说服我。而我在这篇文章中又做了一些解读,发现自己也是没有抓住重点,这才有了今天这篇文章,对之前的这篇文章做一个补充。
从那篇文章后,我了解到Java的参数传递其实牵涉到了Java语言的设计中的参数传递方式,可能在语言设计之时就考虑了这个问题,所以在工作之余自己简单的研究了一下,最终也能根据自己的理解解释一下关于Java是值传递还是引用传递的说法。
Java 是引用传递还是值传递现在有以下这些说法:
1、值传递和引用传递,区分的条件是传递的内容,如果是个值,就是值传递。如果是个引用,就是引用传递。
2、传递的参数如果是普通类型,那就是值传递,如果是对象,那就是引用传递。
3、Java中只有值传递。
关于这个问题应该是分情况讨论的,存在即合理,或许在不同的认识下有不同的说法,也不能简单的就说是值传递还是引用传递。
对或错都是相对的。
回顾在谈这个问题之前我们先了解下值传递和引用传递的概念及现象。可以简单的通过几个例子来讲解的,大概是这样的。
值传递例子1:
public static void main(String[] args){TestJavaParamPass() tjpp = new TestJavaParamPass();
int num = 10;
tjpp.change(num);
System.out.println("num in main():"+i);
}
public void change(int param){
param = 20;
System.out.println("param in change():"+param);
}
控制台输出:
param in change():10num in main():20
mian()方法中的int变量num传递给change()方法,change()方法接收到后将值改变为20。通过看控制台输出,main()方法中的num变量的值没有改变。
结论:实参没有被形参影响,基本类型是值传递。
引用传递例子2:
public static void main(String[] args){TestJavaParamPass() tjpp = new TestJavaParamPass();
User user = new User();
user.setName("Jerry");
tjpp.change(user);
System.out.println("user in mian():"+user);
}
public void change(User param){
param.setName("Tom");
System.out.println("param in change():"+param);
}
控制台输出:
param in change():User(name=Tom}user in mian():User(name=Tom}
main()方法中的user变量传递给change()方法,change()方法改变了其name属性值。通过看控制台输出,main()方法中的user变量的name属性值发生改变。
结论:形参变了实参也变了,引用类型是引用传递。
特殊的值传递例子3:
public static void main(String[] args){TestJavaParamPass() tjpp = new TestJavaParamPass();
String name = "Jerry";
tjpp.change(name);
System.out.println("name in main():"+i);
}
public void change(String param){
param = "Tom";
System.out.println("param in change():"+param);
}
控制台输出:
param in change():Tomname in mian():Jerry
String也是引用类型的数据类型,为什么值没改变?
因为在change()方法里param = "Tom";相当于param = new String("Tom");就相当于param被重新赋值指向了另外一个对象。所以,其实String类型传的是引用,只不过被重新赋值指向了别的对象了,没有修改原对象。即,String本质上还是引用传递,表像上是值传递。
结论:基本类型是值传递,引用类型是引用传递,String是特殊的值传递。
看到这样的结论,没有去深究过,可能大部分程序员的认知都是这样的。
根据上面的例子我们先初步给值传递和引用传递下个定义,以及解释为什么大多数程序员都将String理解为是特殊的值传递。
概念提取与其叫概念提取还不如叫结论总结呢。
值传递:基本类型的变量在被传递给方法时,传递的是该变量的值(即复制自己的值传递给方法)。
引用传递:引用类型的变量在被传递给方法时, 传递的是该变量的引用(即自己所指向的内存地址)。