String作为引用类型,为什么在主方法内调用子方法,子方法修改

2020-04-18  本文已影响0人  蜗牛写java

String作为引用类型,为什么在主方法内调用子方法,子方法修改不了String的值

有趣的小例子

public class StringTest {

   public static void main(String[] args) {
       String str = new String("0");
       System.out.println("+主方法调用子方法前 str = :" + str);
       resetString(str);
       //该处直接上,是不是应该输出 change
       System.out.println("+主方法调用子方法后 str = :" + str);

    }

    private static void resetString(String str) {
       System.out.println("    -子方法中改变前 str = :" + str);
       str = "change";
       System.out.println("    -子方法中改变后 str = :" + str);
    }
}

真实的输出结果

+主方法调用子方法前 str = :0
-子方法中改变前 str = :0
-子方法中改变后 str = :change
+主方法调用子方法后 str = :0

子方法没有起到重置str的作用

因为 String 为 final 修饰的类,所以创建的对象不能改变;str引用变量重新赋值,其实是在堆中是重新创建了一个实例对象,子方法中str引用变量指向了新的实例对象;

public class StringTest {

   public static void main(String[] args) {
       //1 主方法栈帧 中创建 str 引用变量;堆中创建 Stirng 为 0 的对象
       String str = new String("0");
       System.out.println("+主方法调用子方法前 str = :" + str);
       //2 调用子方法
       resetString(str);
       //由 1 2 执行步骤,可以看出 主方法栈帧中的 str引用对象指向的 0 对象没有发生改变
       System.out.println("+主方法调用子方法后 str = :" + str);

    }

    //2.1 主方法栈帧中 压人 子方法栈帧
    private static void resetString(String str) {
       System.out.println("    -子方法中改变前 str = :" + str);
       //2.2 堆中创建 change 对象;子方法栈帧中 str引用变量 执行堆中新创建的 change对象
       str = "change";
       System.out.println("    -子方法中改变后 str = :" + str);
    }
}

图示如下:

栈帧和堆.png
上一篇下一篇

猜你喜欢

热点阅读