关于JAVA函数调用时值传递还是引用传递的问题。

lotte1987 2011-07-11 04:51:43
最近关于一个java引用传递的问题有点纠结
代码如下:
public class abc {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
classAbc abc = new classAbc("This is classAbc");
System.out.println("Class before edit: " + abc.getName());
editClass(abc);
System.out.println("Class after edit: " + abc.getName());

String abcString = new String("This is StringAbc");
System.out.println("String before edit: " + abcString);
editString(abcString);
System.out.println("String after edit: " + abcString);
}

public static classAbc editClass(classAbc abc)
{
abc.setName(abc.getName() + " edited. ");
return abc;
}

public static String editString(String abc)
{
abc = abc + " edited. ";
return abc;
}
}

class classAbc{
private String name;

public classAbc(String name)
{
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

}

执行结果:
Class before edit: This is classAbc
Class after edit: This is classAbc edited.
String before edit: This is StringAbc
String after edit: This is StringAbc

我的问题是,自己写的一个类,作为参数传递给函数的时候函数里对这个类的修改是全局的。就是改完后是全局生效的,即使我没有在调用处接受返回值。有点像C语言里的专递地址。这就是引用传递?
然而用java封装的String类做同样的操作确是局部的修改,就是调用的修改函数结束后修改的内容也丢失。调用处如果不接收返回值则对象不会被修改。这是值传递?
我同样做了int(原始类型)的试验,和String(引用类型)是一样的。
String不是一个类么。为什么跟我自己写的类结果不一样呢,求解?

...全文
222 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
茫茫大海 2011-07-11
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 lotte1987 的回复:]
我试了一下如果在修改函数里加输出语句
public static String editString(String abc)
{
abc = abc + " edited. ";
System.out.println("String in edit: " + abc);
return abc;
}
会输出String in edit: This is StringAbc edited.
这应该意味着在函数里面对引用的修改还是生效了的,推出函数的时候这个修改被复原了。可能是通过函数堆栈信息还是什么的。是这样的吧? 谢了!
[/Quote]
String是引用传递,我前面说过,引用传递引用本身并不会改变,改变的是对象的属性。
十三点elEment 2011-07-11
  • 打赏
  • 举报
回复
手指一抖,十分到手。
茫茫大海 2011-07-11
  • 打赏
  • 举报
回复
楼主可以看看,String的好多操作都返回的是String,也就是说生成了新的String了。所以之前的String并没有改变啊。
lyhmy 2011-07-11
  • 打赏
  • 举报
回复
又是一个值传递和引用传递的问题。。。
lotte1987 2011-07-11
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 pipi517 的回复:]

把String作为引用传递.
public static String editString(String abc)
{
abc = abc + " edited. ";//对引用的改变是无效
return abc;
}
public static classAbc editClass(classAbc abc)
{
abc=new classAbc("This is class……
[/Quote]

我试了一下如果在修改函数里加输出语句
public static String editString(String abc)
{
abc = abc + " edited. ";
System.out.println("String in edit: " + abc);
return abc;
}
会输出String in edit: This is StringAbc edited.
这应该意味着在函数里面对引用的修改还是生效了的,推出函数的时候这个修改被复原了。可能是通过函数堆栈信息还是什么的。是这样的吧? 谢了!
lotte1987 2011-07-11
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 pipi517 的回复:]

把String作为引用传递.
public static String editString(String abc)
{
abc = abc + " edited. ";//对引用的改变是无效
return abc;
}
public static classAbc editClass(classAbc abc)
{
abc=new classAbc("This is class……
[/Quote]

哦。。明白了。是不是如果String有一个setString()的函数用来改变String的值,那就跟我自己写的类一样的效果了?
皮皮 2011-07-11
  • 打赏
  • 举报
回复
把String作为引用传递.
public static String editString(String abc)
{
abc = abc + " edited. ";//对引用的改变是无效
return abc;
}
public static classAbc editClass(classAbc abc)
{
abc=new classAbc("This is classAbcPPPP");//对引用的改变是无效
return abc;
}

引用传递可以改变对象的属性,但是引用本身并不会改变。
lotte1987 2011-07-11
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 langxiashahai 的回复:]

你可以看string类的源码,
public String(String original) {

int size = original.count;

char[] originalValue = original.value;

char[] v;

if (originalValue.length > size) {

//……
[/Quote]

好像是的。应该是java做过特殊封装的结果。开始还不知道。谢了。以后也去多读读源码才是。
lotte1987 2011-07-11
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 pipi517 的回复:]

本来结果应该是一样的。

但是因为java.lang.String类是final类型的类.所以
[/Quote]

试了一下跟 final没有关系。我把自己的类改成final的结果还是变了。
lotte1987 2011-07-11
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 pipi517 的回复:]

本来结果应该是一样的。

但是因为java.lang.String类是final类型的类.所以
[/Quote]

是final的问题么,我去测试看看。谢了啊!
langxiashahai 2011-07-11
  • 打赏
  • 举报
回复
你可以看string类的源码,
public String(String original) {

int size = original.count;

char[] originalValue = original.value;

char[] v;

if (originalValue.length > size) {

// The array representing the String is bigger than the new

// String itself. Perhaps this constructor is being called

// in order to trim the baggage, so make a copy of the array.

int off = original.offset;

v = Arrays.copyOfRange(originalValue, off, off+size);

} else {

// The array representing the String is the same

// size as the String, so no point in making a copy.

v = originalValue;

}

this.offset = 0;

this.count = size;

this.value = v;

}

String的存储实际上通过char[]来实现的,像Integer\Float这些包装类的值操作实际上都是通过对其对应的基本类型操作而实现的。包装类的特质之一就是在对其值进行操作时会体现出其对应的基本类型的性质。在参数传递时,包装类就是如此体现的。所以,对于String在这种情况下的展现结果的解释就自然而然得出了
皮皮 2011-07-11
  • 打赏
  • 举报
回复
本来结果应该是一样的。

但是因为java.lang.String类是final类型的类.所以
lotte1987 2011-07-11
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 hudie1234567 的回复:]

值传递就不说了,引用传递可以改变对象的属性,但是引用本身并不会改变。
[/Quote]

那把String作为函数参数传递是值传递还是引用传递呢?String在java里面是一个类,但是跟我自己写的类的结果就不一样。像是值传递的效果。还有就是java里的引用跟C的指针在实质上是不是可以理解为一样的呢?就是存的是内存地址。谢谢。
茫茫大海 2011-07-11
  • 打赏
  • 举报
回复
值传递就不说了,引用传递可以改变对象的属性,但是引用本身并不会改变。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧