JAVA语言的参数传递: 再一次感慨:java只有值传递 ,之所以有引用传递的假象是由于java中的对象,是通过引用操控的。下面是一个证明java参数是值传递而不是引用传递的一个例子:
public class Test {
public static void exchangeString( String parameterStrA , String parameterStrB )
{
//交换前输出两个形参
System.out.println( "in method exchangeString before exchange :" );
System.out.println( "output parameterStrA@" + parameterStrA );
System.out.println( "output parameterStrB@" + parameterStrB );
//使用临时变量的方法交换两个形参
String s = parameterStrA ;
parameterStrA = parameterStrB;
parameterStrB = s;
//交换后输出两个形参
System.out.println( "in method exchangeString after exchange :" );
System.out.println( "output parameterStrA@" + parameterStrA );
System.out.println( "output parameterStrB@" + parameterStrB );
}
public static void main( String[] args )
{
//初始化并输出两个实参
String argumentStrA = new String( "i'm a" );
String argumentStrB = new String( "i'm b" );
System.out.println( "out of method before exchange:" );
System.out.println( "output argumentStrA@" + argumentStrA );
System.out.println( "output argumentStrB@" + argumentStrB );
//调用交换方法
exchangeString( argumentStrA , argumentStrB );
//输出两个实参
System.out.println( "out of method after exchange:" );
System.out.println( "output argumentStrA@" + argumentStrA );
System.out.println( "output argumentStrB@" + argumentStrB );
//***********************************************************************
String s = new String("s");
s = "ss";
System.out.println( "s is "+s );
}
}
下面为程序输出结果:
out of method before exchange:
output argumentStrA@i'm a
output argumentStrB@i'm b
in method exchangeString before exchange :
output parameterStrA@i'm a
output parameterStrB@i'm b
in method exchangeString after exchange :
output parameterStrA@i'm b
output parameterStrB@i'm a
out of method after exchange:
output argumentStrA@i'm a
output argumentStrB@i'm b
为了进一步说明,再举一个例子
public class TestStringEvaluation{
public static void main(String arg[]){
String string1=new String ("string1 unchanged");
MyString string2=new MyString("string2 unchanged");
System.out.println(string1);
System.out.println(string2.string);
Change a=new Change();
a.ChangeString(string1);
a.ChangeMyString(string2);
System.out.println(string1);
System.out.println(string2.string);
}
}
class Change{
void ChangeString(String temp1){
System.out.println( "before evaluation temp1.hashCode() is " + temp1.hashCode() );
temp1="string1 changed"; //赋值后形参temp1的值发生改变,变为“=”带来的新String对象的引用值。
System.out.println( "after evaluation temp1.hashCode() is " + temp1.hashCode() );
}
//形参temp2虽为实参的一个副本,但temp2.string却并非形参,而是实实在在的
//MyString对象里的公有数据成员string,因此赋值后,temp2.string已经指向了一个新的对象
//"="返回的新String对像,所以在后续的输出时有变化。
//一定要注意 temp2 与 temp2.string的区别
//一个是形参,一个是实际对象里的String对象引用
void ChangeMyString(MyString temp2)
{ System.out.println( "before evaluation temp2.string.hashCode() is " + temp2.string.hashCode() );
temp2.string="string2 changed";
System.out.println( "after evaluation temp2.string.hashCode() is " + temp2.string.hashCode() );
}
}
class MyString
{
public String string;
MyString(String temp)
{
string=temp;
}
}
输出结果是:
string1 unchanged
string2 unchanged
before evaluation temp1.hashCode() is 1239571483
after evaluation temp1.hashCode() is -513711916
before evaluation temp2.string.hashCode() is -557379876
after evaluation temp2.string.hashCode() is 1973800917
string1 unchanged
string2 changed