站内搜索: 请输入搜索关键词

当前页面: 开发资料首页J2SE 专题关于java中的参数传递问题

关于java中的参数传递问题

摘要: 关于java中的参数传递问题


java的参数传递依赖于参数的类型,如果参数是基本类型的变量,则按传值方式。如果参数是引用类型(如类,数组等)的变量,则起传地址的作用,我的问题是关于下面的例子:
public class Canshu
{
static void change(String s,StringBuffer sb)
{
s="aaaa";
sb.setLength(0);
sb.append("aaaa");
}
public static void main(String args[])
{
String s="bbbb";
StringBuffer sb=new StringBuffer("bbbb");
change(s,sb);
System.out.println(s);
System.out.println(sb);
}
}
该程序结果是“bbbb”
“aaaa”
如果按类变量传地址的规则,s的结果应该是aaaa,为什么是bbbb呢?


又出来这个问题了。:(
对于JAVA的非内建类型,其参数本身是个“引用”,而不是个VALUE,所以传递的时候常说“传了个引用”,但这并不等坐于说这种传递就是编译原理说的那种“按引用传递”,那种C++和C#中有,JAVA没有。

换句话说,你可以通过在形参上调用方法或访问成员来修改实参,但对形参本身所引用的对象的修改是影响不了实参的。
——实参本身跟形参一样,也只是个“引用”而已,只有它们在引用着同一个对象的时候,你才能看到那种“修改”的效果,不引用同一个对象了,就没关系了。

不过你用String作试验是无论如何也看不到这个效果的,因为String是个immutable类型:String类没有哪个函数可以修改对象的内容,顶多也就是返回一个新的对象而已。


String 是特殊的对象,它不能被改写


static void change(String s,StringBuffer sb)
{
s="aaaa";
sb.setLength(0);
sb.append("aaaa");
}
里面的s="aaaa";这个引用和
public static void main(String args[])
{
String s="bbbb";
StringBuffer sb=new StringBuffer("bbbb");
change(s,sb);
System.out.println(s);
System.out.println(sb);
}
}
里面的s不是一个东西,change里面那个是s的副本,开始他们都指向"bbbb"而已,你在change里面把副本s改成指向"aaaa"了,并不影响原来那个s


给Areslp(努力ING)写点文字补充:String是一个支持非可 变性的类,这种类的特点是状态固定(不存在任何修改对象的方法),在该对象的生存周期 内,它的值是永远不变的(它是线程安全的).
static void change(String s,StringBuffer sb)
{
s="aaaa";
sb.setLength(0);
sb.append("aaaa");
}
中s="aaaa"是一个新生成的对象,不影响传递进来的参数的值.


谢谢大家的指点,这么说执行下面两个语句:
String s="aaa";
s="bbb";
第一句的s和第二句的s就不是指向同一个地址了?
根本上是String类的特殊性造成的吧?


不是String的特殊性造成的。任何一个非内建类型都是这样,改了指向,指跟原来的那个对象没关系了。

只能说楼主比较倒霉,一个问题没搞明白,结果发这问题里还有另外一个问题在干扰。
当然也可以说比较幸运,因为可以一下子搞懂两个问题。(1)引用类型的参数传递,(2)String的特殊性。


Strings are constant; their values cannot be changed after they are created.
这是jdk上的原话,看看就知道了


对了。。请问大家一个问题?怎么用JAVA进行对数组的操作?如:添加,修改,删除?


只要不是基本数据类型,函数里传过去的都是他们的引用的副本,就是说函数里的s本来是指向"bbbb",但是你在函数里把这个引用指向了一个新的String"aaaa",但也尽限于此。。原来那个s没有任何东西去改动过。当然还是指向bbbb了撒。。


java中只有值传递,没有地址传递,说是引用,其实只是在方法栈中生成指向参数对象的引用变量而已,方法内对变量的赋值,不能反映到调用者


实参本身跟形参一样,也只是个“引用”而已,只有它们在引用着同一个对象的时候,你才能看到那种“修改”的效果,不引用同一个对象了,就没关系了。
 这是关键的一点。
多谢各位,这回总算是搞清楚了。


为什么要改引用的副本的指向,而不根据引用的副本去改它指向的内容呢,还是因为大家所说的String对象不允许修改的缘故,它是constant.
对于其它非内建类型,应该是根据引用的副本去改它指向的内容,而不是要改引用的副本的指向吧?


String s="bbbb";
到这一句话的时候就把s的指向变了



大家说得都很对,谢谢大家指点,我现在才明白大家的意思。
对于语句A a=new A();是先由new A()产生一个对象,然后让a指向它,而不是在a(假如a以前赋过值)指向的地方存放new A()产生的对象。

例如:public class Canshu4
{

static void f(A v)
{
v=new A(2);
}
public static void main(String args[])
{A a=new A(8);
f(a);
System.out.println(a.i);
}

}
最后输出结果是8而不是2。


我还想列举下面例子
String s="aaa";
String b="aaa";
System.out.println(s==b);
此时结果为true,是不是系统也会先检查“aaa”是否存在,如果存在就让b指向它,因此s和b指向同一个对象呢



由此下面两个例子也就很明白了
example1:
public class Canshu5
{

static void f(A v)
{

v.c=new A(7);
}
public static void main(String args[])
{A a=new A(8);
a.c=new A(4);
f(a);
System.out.println(a.i);
System.out.println(a.c.i);
}

}

class A
{int i;
A c;
A(int i)
{this.i=i;}

}
的结果是8,7而不是8,4。


example2:
public class Canshu6
{

static void f(A v)
{

v=new A(7);
}
public static void main(String args[])
{A a=new A(8);
a.c=new A(4);
f(a.c);
System.out.println(a.c.i);
}

}

class A
{int i;
A c;
A(int i)
{this.i=i;}

}
的结果是4而不是7


↑返回目录
前一篇: 新手问题:显示命令行传给main()参数
后一篇: 问一个面向对象的弱问题