java中容器Vectort用add添加对象是对象引用的问题

来源:互联网 发布:迷奇化妆品怎么样知乎 编辑:程序博客网 时间:2024/05/16 04:31

                    java中容器Vectort用add添加对象是对象引用的问题

   众所周知的是在java中去掉了c++中的最为神奇的指针,但是java中存在着引用(个人认为java中的引用与c++的指针很相似,只是不能如指针那般使用)。引用,我们可以通俗的将其认为是某一块内存的地址指针,只要学过c语言的都知道,值传递和地址传递区别是很大。而在java中似乎一直存在着一个争论,java到底是值传递还是引用传递,我查阅了很多资料,得出一个结论,就是不能一概而论,个人认为可以看做是java中值传递,引用传递两者都存在。简单点可以这样认为,变量是值传递,而一般对象是引用传递。

      变量是值传递:

        比如  

                 int a=111; int b=a; System.out.println("第一次b=:"+b); a=222; System.out.println("第二次b=:"+b);

     结果截图


         

可以看到b的值并没有因为a的值改变而改变,所以这种情况是值传递,a只是把自己的值传给了b;也有种说法是,在第一次int b=a时,a将自己的引用给了b,a和b指向同一个内存地址。 当a再次被赋值,a=222;时,a已经是代表另一个引用了,而b依然指向之前的地址。至于是怎么样的,见仁见智了,个人偏向第一种。在变量中无论怎么样理解都没有问题,但是在操作对象时就会出现完全不同的效果。

      现在进入今天的重点,在容器中操作对象的的引用问题。

首先,我必须说明,一般在使用对象时,都是引用传递的

接下来通过一些测试来说明我的判断

首先定义一个card类,用容器Vector来操作card实例。card定义代码如下

public class Card {String name="name";Card(String n){name=n;}public void setName(String n){name=n;}public String  getName(){return name;}}

测试一,代码如下:

import java.awt.List;import java.util.Vector;public class Ceshi {public static void main(String[] args) {String temp1="",temp2="",temp3="";Vector<Card> cards=new Vector<Card>();Card card1=new Card("old card1");cards.add(card1);temp1=cards.get(0).getName();card1.setName("new card1");temp2=cards.get(0).getName();System.out.println("第一次:"+temp1);System.out.println("第二次:"+temp2);}}

结果截图



上面的代码很简单,首先将card的一个实例card1通过容器Vector的add方法装到cards中,打印cards中添加元素的那么参数值,接着改变card1的参数name值,打印cards中元素的name参数值。从结果可以看到,容器cards的添加的元素name会随着card1变化而变化,这就说明容器通过add添加的只是一个card1的引用了而已。


测试二,代码如下

import java.awt.List;import java.util.Vector;public class Ceshi {public static void main(String[] args) {String temp1="",temp2="",temp3="",temp4="";//生成两个card类的容器Vector<Card> cards=new Vector<Card>();Vector<Card> newCards=new Vector<Card>();        //生成两张card实例Card card1=new Card("old card1");Card card2=new Card("old card2");        //将两个card实例装入cardList容器中。cards.add(card1);cards.add(card2);        //将容器cards中的card实例都添加到newCards中newCards.addAll(cards);temp1=newCards.get(0).getName();temp2=newCards.get(1).getName();card1.setName("new card1");card2.setName("new card2");temp3=newCards.get(0).getName();temp4=newCards.get(1).getName();System.out.println("第一次:"+temp1);System.out.println("第一次:"+temp2);System.out.println("第二次:"+temp3);System.out.println("第二次:"+temp4);}}

结果截图如下:



从结果截图来看,容器使用addAll,也是引用用传递。


测试三,代码如下:

import java.awt.List;import java.util.Vector;public class Ceshi {public static void main(String[] args) {String temp1="",temp2="",temp3="",temp4="",temp5="",temp6="";//生成card类的容器Vector<Card> cards=new Vector<Card>();        //生成两张card实例Card card1=new Card("old card1");Card card2=new Card("old card2");        //将两个card实例装入cardList容器中。cards.add(card1);cards.add(card2);        //用new生成一个容器,同时进行初始化,将cards赋给它Vector<Card> newCards=new Vector<Card>(cards);temp1=newCards.get(0).getName();temp2=newCards.get(1).getName();//通改变card1和card2,改变所有共同的引用card1.setName("new card1");card2.setName("new card2");temp3=newCards.get(0).getName();temp4=newCards.get(1).getName();cards.get(0).setName("new card1 again");cards.get(1).setName("new card2 again");temp5=newCards.get(0).getName();temp6=newCards.get(1).getName();System.out.println("第一次:"+temp1);System.out.println("第一次:"+temp2);System.out.println("第二次:"+temp3);System.out.println("第二次:"+temp4);System.out.println("第三次:"+temp5);System.out.println("第三次:"+temp6);}}


结果截图如下:




测试三中,可以看到 card1和card2与cards,newCards对应元素共享同一个引用,即指向同一个地址,三者之间任何一个改变引用所指地址的内容,其他两者的内容都会改变。这也再次说明了,一般而言  对象是引用传递。

所以在传递对象时,一定要小心,是否要共享。 




     

1 0
原创粉丝点击