关于函数参数的引用和复制
有如下程序,对于部分参数在调用函数时被复制(如:String, arry, Object(可能Object不算));有些被引用(如:HashMap)
想问下,那些类型的变量调用函数时被复制,哪些被引用?
多谢先!
--------------
import java.util.HashMap;
public class Test1 {
public static void main(String[] args) {
String s= "s1 ";
Object o = "o1 ";
int[] a = new int[]{1,2,3};
HashMap h = new HashMap();
h.put( "h1 ", "v ");
f(s, o, a, h);
System.out.println( "string= " + s);
System.out.println( "object= " + o);
System.out.println( "array= " + a.length);
System.out.println( "hashmap= " + h.size());
}
static void f(String s, Object o, int[] a, HashMap h){
s += "__ ";
o = "222 ";
a = new int[]{1,2,3,4};
h.put( "2 ", "v2 ");
}
}
-----------结果:
string=s1
object=o1
array=3
hashmap=2
------解决方案--------------------楼主如果有一些c的基础也许容易理解一些。在java里面, 函数调用时, 参数传递的简单类型(int, char等)会被复制, 因此在函数中对这些参数的修改在函数退出是会丢失。参数传递的对象类型实际上传递的是引用, 也就是指针, 指针的本质也是一个整数, 因此这个引用会被复制一份, 但是这个引用指向的对象不会被复制。因此, 在函数中, 通过参数对对象的操作不会丢失, 但是对这个引用的重新赋值会丢失。 在你的代码中,
s += "__ "; //这个是对s的重新赋值, 丢失
o = "222 "; //同上
a = new int[]{1,2,3,4}; //同上
h.put( "2 ", "v2 "); //通过引用来操作对象, 不会丢失
------解决方案--------------------只要不是简单类型就会被引用,String和HashMap不同的地方是String是一个内容不可改变的对象,就是说如果你想改变一个String,你得到必然是一个新的String
可以看看lz的代码对4个变量的操作,前3个都是在赋值,最后是对map的put
f(String s, Object o, int[] a, HashMap h) 在调用这个方法的时候,s,o, a, h是在栈中的临时变量,也就是说只有在
这个方法的生命周期内才有效,(lz做c很多年应该知道传值和传地址的区别吧, 指针也是变量只不过我们操作他的规则很特
殊), 对前3个变量的操作都是对变量本身的操作(赋值), 没有对他们指向的对象做操作,又能期望那些对象有什么改变呢?
而对第4个的操作是对h这个变量指向的对象的操作( map.put() )
如果对第4个变量的操作也是h=new HashMap(); 那么结果就是什么也没有变化
------解决方案--------------------to 楼主:
只要是类的实例,就不会被复制,String也一样,没有特殊性。数组虽然不是类的实例,但也是做为对象而存在的,所以也不会被复制。
被复制的类型只有简单类型,具体地说,是boolean, char, byte, short, int, long, float, double这八种。
另外,对象的引用(JAVA中叫引用,其实就是对象的地址,相当于C++的指针)本身是被复制的。这和C++中的指针会被复制是一个道理。
本质上,JAVA中所有的赋值操作以及函数的参数传递及值返回都是复制的。但对于简单类型和非简单类型,其复制的内容有所不同,对于简单类型复制的是对象本身,而对于非简单类型复制的是对象的地址。JAVA不允许程序员自己来选择是复制对象本身还是复制地址。
C++新手,有时甚至是有经验的程序员也往往要花大量时间来研究复制控制,而JAVA简化了所有的这些。在JAVA中,你只要记住:简单类型和地址永远是复制的,而除此之外都是不复制的。
JAVA提供一个复制非简单类型的方法,clone(),但这个方法也是复制对象的表层,对于所有的非简单类型对象成员都是复制其地址,clone()是一种“浅复制”。
------解决方案--------------------全部都是引用。
string=s1 //因为函数中用=重新赋值了(new了新实例),改变了地址,不再指向原来实例了,下同
object=o1
array=3
hashmap=2 //因为函数中调用了类似于设置之类的方法,改变了内容
------解决方案--------------------xingyue2003() ( ) 信誉:100 Blog 2007-3-7 8:32:01 得分: 0
java的基本类型和string的对象会被复制,其他的是引用,如果前者是数组的话也是引用,因为数组可以被看作是array对象
---------------------------------
不要误导人家,只有基本类型才是复制,String是类不会被复制.数组在java里是和类一样的不会被复制.