日期:2014-05-20  浏览次数:20785 次

Str的值没有传过去,why ?
首先,请看代码:

public class A{
private String[] _str = {"早班","晚班","小夜班","大夜班"};
public void toNew(String string,int flag){
switch(flag){
case 0:string = _str[0];break;
case 1:string = _str[1];break;
case 2:string = _str[2];break;
case 3:string = _str[3];break;
default:
System.out.println("哥们儿,按规矩办事,请输入1、2、3、4中任意一个");break;
}
}
public static void main(String[] arg0){
String str = null ;
new A().toNew(str,3);
System.out.println(str);
}
}


结果:null

---------------------分割线---------------------

问题:
  结果为null,很出乎我的意料!
如果说,String[] _str 不是类周期的生命线我还想得通,但是 !!! _str的生命周期是类周期的,
也就是说,_str是不受到toNew()这个函数影响的,
那么,在toNew()里面,让一个传入参数获取 _str的值,为什么错了呢?
换句话说,为什么toNew(String string,int i)中 str = _str为什么除了函数toNew的范围数据就null了呢?


请看图:

------解决方案--------------------
string是值传递,又不是引用传递,当然是null了。。。
------解决方案--------------------
不是说了是值传递么;

你想象一下你在toNew方法里改变flag的值,你觉得会影响main里你传的flag的值?
------解决方案--------------------
toNew方法没有返回值并且赋于str,当然是null了,你这方法走不走一样
------解决方案--------------------
String是一个不可变类,针对String对象,JVM使用了常量池,并且专门为string准备了CONSTANT_String_info结构,结构中存放的是到常量池中的索引。

所以一旦string对象变化,jvm会重新从常量池为字符串参数ldc一个新的string索引,而原string对象索引的常量保持不变。

以你的程序为例:
jvm实际上是ldc <String "小夜班">,然后astore_1 [string]
可是main中的字符串变量str,索引依然是null
------解决方案--------------------
这个一定要考虑值传递还是地址传递的问题。首先:java里面没有指针,java里面做地址传递的方式就是使用非基础数据类型,例如对象,数组等等。字符串作为一种基础数据类型,不可以用来进行地址传递。楼主的例子是值传递的。把String类型改成Int类型,结果还是默认值。要解决这种情况我想到了两种方式。第一种就是把传入的保存结果的类型改成对象或者数组;第二种方式,去掉保存结果的参数,将结果作为返回值返回。
------解决方案--------------------
public class A{
    private String[] _str = {"早班","晚班","小夜班","大夜班"};