java 字符串参数传递和修改(个人见解)

首先贴出一道面试题

public class Example{
    String str = new String("good");
    char[ ] ch = { 'a' , 'b' , 'c' };
    public static void main(String args[]){
        Example ex = new Example();
        ex.change(ex.str,ex.ch);
        System.out.print(ex.str + " and ");
        System.out.print(ex.ch);
    }
    public void change(String str,char ch[ ]){
        str = "test ok";
        ch[0] = 'g';
    }
}

当然答案也先贴出:

good and gbc

解析

1.首先按照正常的思路来思考

这里的change方法的参数,传递的是str和ch数组的地址,而在方法体内修改了str的值答案应该是:test ok and gbc。

2.问题1:字符串传参是值传递还是地址传递?

自己思考的答案和运行结果不同肯定是有问题的。
我们先打印一下各个代码块中的地址:

public class Test {
    String str = new String("good");
    char[ ] ch = { 'a' , 'b' , 'c' };
    public static void main(String args[]){
        Test ex = new Test();
        // 方法运行前,成员变量str的地址
        System.out.println("1-" + System.identityHashCode(ex.str));
        
        ex.change(ex.str,ex.ch);
        // 方法运行后,成员变量str的地址
        System.out.println("2-" + System.identityHashCode(ex.str));
        
        System.out.print(ex.str + " and ");
        System.out.print(ex.ch);
    }
    public void change(String str,char ch[ ]){
        // 方法体修改局部变量str的值之前的地址
        System.out.println("3-" + System.identityHashCode(str));
        
        str = "test ok";
        
        // 方法体修改局部变量str的值之后的地址
        System.out.println("4-" + System.identityHashCode(str));
        
        ch[0] = 'g';
    }
}

运行结果:

1-1872034366
3-1872034366
4-1581781576
2-1872034366
good and gbc

从上面可以看到,在传递字符串参数的时候,传递的是字符串的指针的一个副本,是属于值传递,在修改之前地址和成员变量str的地址相同,但是修改之后就不同了,由于字符串常量是在编译时期就已经创建的内存空间,既然创建了就有地址,当在传递字符串参数时,由于没有修改,所以传递的副本指针指向的内存和成员变量指针指向的内存的地址相同,但是修改之后,就是将新字符串的地址传递给了副本指针str,使得副本指针地址改变,但是没有改变原指针的指向。

2.问题2:字符串改变到底是内存地址改变还是内存中的值改变

首先在上面代码进行一些修改:

public class Test {
    String str = new String("good");
    char[ ] ch = { 'a' , 'b' , 'c' };
    public static void main(String args[]){
        Test ex = new Test();
        ex.change(ex.str,ex.ch);
        System.out.print(ex.str + " and ");
        System.out.print(ex.ch);
    }
    public void change(String str,char ch[ ]){
        System.out.println("1-" + System.identityHashCode(str));
        str = "test ok";
        System.out.println("2-" + System.identityHashCode(str));
        str = "test oj";
        System.out.println("3-" + System.identityHashCode(str));

        ch[0] = 'g';
    }
}

运行结果

1-1872034366
2-1581781576
3-1725154839
good and gbc

由上可知,参数传递过来指针指向的地址是1-1872034366,修改之后指向2-1581781576,再次修改之后指向3-1725154839,所以,字符串改变实际上是将指针指向了另一块内存,并不是将指向内存中的值改变。

结论

  • 字符串传参是值传递,是将原来变量的指针(引用)复制一份传递给方法,但是他们指向的内存是同一个。
  • 字符串常量是在编译时期就已经创建了内存空间,改变字符串常量其实就是改变指针的指向地址,从指向一个常量变为指向另一个常量。
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值