今天一个同事也碰到一个问题,问题大致是这样的:
有一个list1对象:
ArrayList list1=new ArrayList();
list1.add(“string1”);
list1.add(“string2”);
这时候又定义了一个list2, 并将list1赋值给list1,然后对list2进行修改,发现list1也改变了:
ArrayList list2 = list1;
List2.add(“string1”);
于是同事再次,试验了:
ArrayList list2 = new ArrayList();
list2 = list1;
list2.add(“string1”);
结果发现list1还是被修改了~~这个问题是属于java中比较常见的一个问题,即java的值传递与引用传递问题。下面对其进行简单的介绍:
java值传递与引用传递
1、对象是按引用传递的---带"="号的赋值操作
2、Java 应用程序有且仅有的一种参数传递机制,即按值传递---由"函数调用"引起的
3、按值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本
4、按引用传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本
5、注意:String虽是对象,但永远是传值
首先我们来看看第一点:对象是按引用传递的确实,这一点我想大家没有任何疑问,例如:
class Test01
{
public static void main(String[] args)
{
StringBuffer s= new StringBuffer("good");
StringBuffer s2=s;
s2.append(" afternoon.");
System.out.println(s);
}
}
对象s和s2指向的是内存中的同一个地址因此指向的也是同一个对象。
如何解释“对象是按引用传递的”的呢?
这里的意思是进行对象赋值操作是传递的是对象的引用,因此对象是按引用传递的,有问题吗?
程序运行的输出是:
good afternoon.
这说明s2和s是同一个对象。
这里有一点要澄清的是,这里的传对象其实也是传值,因为对象就是一个指针,这个赋值是指针之间的赋值,因此在java中就将它说成了传引用。(引用是什么?不就是地址吗?地址是什么,不过就是一个整数值)
再看看下面的例子:
class Test02
{
public static void main(String[] args)
{
int i=5;
int i2=i;
i2=6;
System.out.println(i);
}
}
程序的结果是什么?5!!!
这说明什么,原始数据类型是按值传递的,这个按值传递也是指的是进行赋值时的行为。
下一个问题:Java 应用程序有且仅有的一种参数传递机制,即按值传递
class Test03
{
public static void main(String[] args)
{
StringBuffer s= new StringBuffer("good");
StringBuffer s2=new StringBuffer("bad");
test(s,s2);
System.out.println(s);//9
System.out.println(s2);//10
}
static void test(StringBuffer s,StringBuffer s2) { //此时会在方法栈中新建引用,但指向同一内存地址
System.out.println(s);//1
System.out.println(s2);//2
s2=s;//3
s=new StringBuffer("new");//4
System.out.println(s);//5
System.out.println(s2);//6
s.append("hah");//7
s2.append("hah");//8
}
}
程序的输出是:
good
bad
new
good
goodhah
bad
为什么输出是这样的?
这里需要强调的是“参数传递机制”,它是与赋值语句时的传递机制的不同。
我们看到1,2处的输出与我们的预计是完全匹配的
3将s2指向s,4将s指向一个新的对象
因此5的输出打印的是新创建的对象的内容,而6打印的原来的s的内容
7和8两个地方修改对象内容,但是9和10的输出为什么是那样的呢?
Java 应用程序有且仅有的一种参数传递机制,即按值传递。
所以,最上面的那个问题的解决方法如下:
ArrayList list1=new ArrayList();
list1.add(“string1”);
list1.add(“string2”);
ArrayList list2 = new ArrayList();
for(int i = 0; i < list1.length; i++) {
list2.add(list1.get(i));
}
这样再对list1进行修改,就不会影响到list2了。
分享到:
相关推荐
不管是按值传递还是按引用传递,都是把栈中的数据备份了一份给参数变量,只不过值类型备份的是具体的数值,而引用类型备份的是内存地址
java 值传递和引用传递的比较区别,包括代码及详解
Java:按值传递还是按引用传递详细解说
Java面向对象值传递和引用传递Java面向对象值传递和引用传递Java面向对象值传递和引用传递Java面向对象值传递和引用传递
13.java参数传递之引用传递.zip13.java参数传递之引用传递.zip13.java参数传递之引用传递.zip13.java参数传递之引用传递.zip13.java参数传递之引用传递.zip13.java参数传递之引用传递.zip13.java参数传递之引用传递....
这个在Java里面是经常被提起的问题,也有一些争论,似乎最后还有一个所谓的结论...事实上,这很容易让人迷惑,下面先分别看看什么是按值传递,什么是按引用传递,只要能正确理解,至于称作按什么传递就不是个大问题了。
java学习java语言的值传递和引用传递
本人经过长时间收集的最经典、最有说服力、最易懂的关于值传递和引用传递的详解资料~包看包会~发出去真有些不舍得~
当一个变量为一个参数传入方法内部的时候,会有两种不同的传递方式:值传递和引用传递。 值传递的特点:不管方法内部对传进去的参数作任何改变,也不会影响方法外部的变量的值 引用传递的特点:方法内部对传...
java参数传递时到底是值传递还是引用传递分享.pdf
java参数传递时到底是值传递还是引用传递[归类].pdf
主要介绍了 Java 值传递和引用传递详解及实例代码的相关资料,需要的朋友可以参考下
主要介绍了详解java的值传递、地址传递、引用传递的相关资料,需要的朋友可以参考下
Java中的值传递和引用传递的区别.doc
Java语言中参数值传递和引用传递比较
主要介绍了java到底是值传递还是引用传递的相关知识,本文通过几个例子给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
Java的按值传递和按引用传递分析 Java的按值传递和按引用传递分析.pdf
java中的值传递和引用传递[汇编].pdf
java 中没有引用传递,都是值传递的,可以通过传递副本修改对象的,副本交换,并不影响原引用