有如下程序,对于部分参数在调用函数时被复制(如: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

解决方案 »

  1.   

    java的基本类型和string的对象会被复制,其他的是引用,如果前者是数组的话也是引用,因为数组可以被看作是array对象
      

  2.   

    h.put("h1", "v");//v被引用
    f(s, o, a, h);//s,o,a被复制,h被引用
    h.put("2", "v2");//v2被引用
      

  3.   

    前者是数组的话也是引用,因为数组可以被看作是array对象
    h.put("h1", "v");//v被引用
    f(s, o, a, h);//s,o,a被复制,h被引用
    h.put("2", "v2");//v2被引用
      

  4.   

    int[] a = new int[]{1,2,3};

    HashMap h = new HashMap();都是集合类型吧,
    为什么前者是复制,后者是引用呢?
      

  5.   

    int[] a = new int[]{1,2,3};

    HashMap h = new HashMap();都是集合类型吧,
    为什么前者是复制,后者是引用呢?
    -------------------------------------------
    麻烦说清楚点,new关键字是干什么的。
      

  6.   

    只要是Object(包括数组和String),就都是引用。简单类型(int, char等)才会被复制。
      

  7.   

    楼主如果有一些c的基础也许容易理解一些。在java里面, 函数调用时, 参数传递的简单类型(int, char等)会被复制, 因此在函数中对这些参数的修改在函数退出是会丢失。参数传递的对象类型实际上传递的是引用, 也就是指针, 指针的本质也是一个整数, 因此这个引用会被复制一份, 但是这个引用指向的对象不会被复制。因此, 在函数中, 通过参数对对象的操作不会丢失, 但是对这个引用的重新赋值会丢失。 在你的代码中,s +="__"; //这个是对s的重新赋值, 丢失
    o = "222"; //同上
    a = new int[]{1,2,3,4}; //同上
    h.put("2", "v2"); //通过引用来操作对象, 不会丢失
      

  8.   

    多谢大家回复,可能我没有将问题讲清楚。
    C和java都做了好多年了,指针、地址这些概念还是清楚的。
    我想问在java这么多种类型里,那些类是会被复制的,那些类会被引用。(2种类的特征是什么)To Dan1980:
    为何String有其特殊性,从String的源代码哪里可看出。
    HashMap和String都是同样继承Object为何有不同呢?To mainGalaxy(天狼星):
    我在h.put("2", "v2");后加了句new HashMap();但结果没边,这样看起来好像是复制,是吗?Thanks!
      

  9.   

    建议楼主看一下《thinking in java》,里面有一章对到底是引用还是复制做了非常详细的解释。
      

  10.   

    只要不是简单类型就会被引用,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(); 那么结果就是什么也没有变化
      

  11.   

    String的这个特点很重要,这就是为什么我们总是使用String 做Map的key,因为它不会改变
    原始类型的包装类也是这样的,也是做map的key的好东东,因为对象的改变会使它本身的hashCode改变,这样HashMap就会重新hash,
      

  12.   

    to 楼主:只要是类的实例,就不会被复制,String也一样,没有特殊性。数组虽然不是类的实例,但也是做为对象而存在的,所以也不会被复制。被复制的类型只有简单类型,具体地说,是boolean, char, byte, short, int, long, float, double这八种。另外,对象的引用(JAVA中叫引用,其实就是对象的地址,相当于C++的指针)本身是被复制的。这和C++中的指针会被复制是一个道理。本质上,JAVA中所有的赋值操作以及函数的参数传递及值返回都是复制的。但对于简单类型和非简单类型,其复制的内容有所不同,对于简单类型复制的是对象本身,而对于非简单类型复制的是对象的地址。JAVA不允许程序员自己来选择是复制对象本身还是复制地址。C++新手,有时甚至是有经验的程序员也往往要花大量时间来研究复制控制,而JAVA简化了所有的这些。在JAVA中,你只要记住:简单类型和地址永远是复制的,而除此之外都是不复制的。JAVA提供一个复制非简单类型的方法,clone(),但这个方法也是复制对象的表层,对于所有的非简单类型对象成员都是复制其地址,clone()是一种“浅复制”。
      

  13.   

    全部都是引用。string=s1 //因为函数中用=重新赋值了(new了新实例),改变了地址,不再指向原来实例了,下同
    object=o1
    array=3   
    hashmap=2 //因为函数中调用了类似于设置之类的方法,改变了内容
      

  14.   

    我在h.put("2", "v2");后加了句new HashMap();但结果没边,这样看起来好像是复制,是吗?==========
    如果你是:
    h = new HashMap();
    h.put("2", "v2");
    你将得到:
    hashmap=1感觉楼主是不是思维进死胡同了??
      

  15.   

    xingyue2003() ( ) 信誉:100    Blog  2007-3-7 8:32:01  得分: 0  
     
     
       
    java的基本类型和string的对象会被复制,其他的是引用,如果前者是数组的话也是引用,因为数组可以被看作是array对象
    ---------------------------------
    不要误导人家,只有基本类型才是复制,String是类不会被复制.数组在java里是和类一样的不会被复制.  
     
      

  16.   

    很感谢大家热情回复。
    收获不少也解决了这个问题。特别是Dan1980的:简单类型和地址永远是复制的,而除此之外都是不复制的。
    之前有这个困惑也是由于对String的不了解。很感谢Veryx和jianfengqu对String的解释。Many thanks you all!