Java中数据传递问题
C语言的函数中参数如果是基本数据类型,是按值传递的,方法中变量值的变化不影响方法外变量的值,如果是基本类型的引用类型,则是按地址传递的。而结构体或类对象是按地址传递的,方法中变量的变化直接影响到方法外变量。但java中情况有变。先来看看以下三个例子:
//Test1.java
publicclass Test1{
publicstatic void fun(String s){
s="haha";
}
publicstatic void main(String[] args) {
Strings="hehe";
fun(s);
System.out.println("s="+s);
}
}
输出结果:s=hehe
(这里,调用fun()后,s的值未改变)
//Test2.java
importjava.util.*;
publicclass Test2{
publicstatic void fun(Vector v){
v.addElement("haha");
v.addElement("hehe");
}
publicstatic void main(String[] args) {
Vectorv=new Vector();
fun(v);
System.out.println("vis:");
for(inti=0,n=v.size();i<n;i++){
System.out.println((String)v.elementAt(i));
}
}
}
输出结果是:
v is:
haha
hehe
(这里,调用fun()后,v的值改变了)
Test3.java
importjava.util.*;
publicclass Test3{
publicstatic void fun(Vector v){
Vectorv1=new Vector();
v1.addElement("haha");
v1.addElement("hehe");
v=v1;
}
publicstatic void main(String[] args) {
Vectorv=new Vector();
fun(v);
System.out.println("vis:");
for(inti=0,n=v.size();i<n;i++){
System.out.println((String)v.elementAt(i));
}
}
}
得到的结果是v的大小是0,和Test1的结果是一致的。
public class Tester {
public static void main(String[] args) {
int primitive = 2;
MyClassmyClass = new MyClass();
changeObject(myClass);
}
publicstatic void changeObject(MyClass myClass) {
myClass.i = 3;
myClass = new MyClass();
//myClass可看作一个局部变量,它保存的是外部传入的对象引用,通过new MyClass()得到的引用只会改变此局部变量myClass的值,不会影响到外部
}
}
class MyClass {
int i;
}
//myClass仍然指向的是执行changeObject之前的那个对象
//但是myClass.i等于3了
方法中的参数可以分为原语(或基础)类型、不可变对象类型和可变对象类型。
如果参数是不可变对象类型(i.e.BigInteger,String)或原语类型(i.e.int) 这样的参数是安全的,方法体内的任何动作都不会影响方法外的内容。
对于可变对象的类型,如Vector v对v调用add()、remove()等方法会导致方法外的变量的变化,这时可能会导致代码的不安全。但是如果在方法体内对该参数有重新赋值的操作,如v = new Vector(),这样v指向的地址已经变化,之后对v的任何操作也不会影响方法外的内容。
根据《Effective Java Programming》推荐,不可变对象是线程安全的,而且易于使用,如果没有特殊要求的话,应该尽量使用。