JAVA基础问题,到底是值传递还是引用传递?

值传递还是引用传递的问题,请看下面代码和注释。
public class Test {
public static void main(String[] args) {
Test t = new Test();
String[] strs = {"strs[0]"};
String str = "str";
t.xg(strs, str);
System.out.println(strs[0]+"\t"+str);
}
public void xg(String[] strs,String str) {
strs[0] = "修改后的strs[0]";
str = "修改后的str";
}
}
打印结果是 "修改后的strs[0] str"。
很显然,strs发生 了变化,str没有变化(我的理解是,都不变,JAVA是值传递的),为什么会这样?帮忙解释一下!
另外,我试了多次,发现,好像,主要问题在数组和非数据元素传递的区别,而不是什么基本数据类型什么对象的区别。

java中方法参数传递方式是按值传递。所谓值传递,就是将实际参数值的副本(复制品)传入方法内,而自己本身不会受到任何影响。
如果参数是基本类型,传递的是基本类型的字面量值的拷贝。 

如果参数是引用类型,传递的是该参量所引用的对象在堆中地址值的拷贝。

温馨提示:答案为网友推荐,仅供参考
第1个回答  2009-03-02
传递的是对象没错,问题出在str = "修改后的str"; 这一句上。
这句话表示新建一个对象,内容是“修改后的str”,然后赋给str
因此,原对象内容并没有发生变化。这也是java和c++不同的地方。

String[]和int[]中存放的是指向对象的地址,因此修改后它的值可以返回到主函数中。这个是毋庸置疑的。
数组也是一样,因为数组传递的是地址(我这么认为)因此,你对对象的改变就会反应到主函数中。

你采用的String 和 String[]变量的区别是:String变量传递的是一个对象,当它被赋予一个新对象内容时,原对象不会发生变化。而String[]是一个数组,传递的是对象的地址。新对象赋给新地址,地址没有变,但对象变了,因此String【】内容变了。
第2个回答  推荐于2017-11-27
public void xg(String[] strs,String str) {
strs = new String[]{"修改后的strs[0]"};
str = "修改后的str";
}
你把你的这个方法改成这样你发现连数组都改不了。本来在主函数调用的时候传进来的str是“str”,他这个时候是“str”的地址,和主函数是同一个对象,你在这个函数里选择了重新创建对象,再把创建的对象赋值给你这个函数里的str这个引用,但是这个时候问题就来了,你函数里的str和主函数的str这个时候不是同一个对象了。在主函数里的那个对象在内存里一点都没变化,你所做的只不过是把原本是他的引用给了你自己创建的那个对象了。而传入的String本来是毫发无损,所以主函数打印出来还是原来的值。
再回到你的数组上,你是改变数组的内容,而不是去创建新数组,你改变的数组和传入的数组是同一个对象,肯定也就改变了主函数里的数组了。当然如果说你只是改变传入的String的属性的话也是可以改变主函数的里的String的,不过string是个常量你改不了什么东西。

要不是还不明白给我留言,我都差点被你给问懵了。哈哈本回答被提问者采纳
第3个回答  2009-03-02
首先,java是一种面向对象的语言,除了八种基本数据类型其他一切皆对象。并将对象抽象为类。
8种基本数据类型包括:byte,int,char,long,boolean,double,short,float。
在java语言中,若使用8种基本类型就是值传递,若是对象那就是引用传递了。
String需要注意的是:String不是8种基本类型中的一种,它已被抽象成类了。
String对象的值一旦确定不可改变,String str = "str"; 作用域是main方法。
str = "修改后的str"; str引用了新的String对象("修改后的str"; ),但作用域仅在该方法内,贴上代码自己去试。
---------------Test.java----
public class Test {
public static void main(String[] args) {
Test t = new Test();
String[] strs = {"strs[0]"};
String str = "str";
t.xg(strs, str);
System.out.println(strs[0]+"\t"+str);
}
public void xg(String[] strs,String str) {
strs[0] = "修改后的strs[0]";
str = "修改后的str";
System.out.println("xg方法内:---------》"+str);
}
}
————————————结果——————
xg方法内:——————————————》修改后的str
修改后的strs[0] str
---------------------
第4个回答  2009-03-02
对象就像是存储空间的别名,虽然名字不一样,但是他指的是同一个地址,所以无论你是用真名改它的值还是别名都是一样的,但是基本的数据类型就不了,你别看他们是同名的,但是指的肯定是两个存储地址,是不一样的,所以你无论改哪个都不会两个一起改动