String类型和数组类型引用的区别

1. 题目引入

我们先来看这么一道题目,读者可以先尝试做一下:

                 选项A:  tarena and abc                         选项B: tarena and gbc

                 选项C: test ok and abc                          选项D: test ok and gbc

你会选择哪一个呢?我一开始选择的是D,但是正确答案是B!!!数组里面的值改变了,但是String类型的值没有改变.

同样是引用类型,string类型和数组类型到底有什么区别呢,接下来我们分别介绍它们的特点和机制.

2. String类型引用

String str = new String("tarena");

这个语句执行的时候:

首先会检查字符串常量池有没有“tarena”,如果没有,就在字符串常量池创建一个“tarena”,然后根据字符串常量池的“tarena”,在堆中创建一个“tarena”对象,这个str指向堆中的“tarena”对象;如果字符串常量池有“tarena”,就直接在堆中创建一个“tarena”对象.

总的来说,就是在堆中有一个str成员变量,指向堆中的一个地址A,地址A中的值是“tarena”.且由于字符串是不可变的,那么这个地址A的值“tarena”是不变的.str的指向的字符串常量的值始终是“tarena”,除非将str指向其他地址.

3. 数组类型引用

在Java中,数组也是一种引用类型,但是相较于String类型,数组中引用的值是可以修改.

char[] ch = {"a","b","c"};

同样,上面语句在堆中创建一个成员变量ch,并创建一个地址B,B中的值是数组的元素:"a","b","c",该成员变量ch指向地址B.

4.题目具体分析  

public void change(String str,char ch[]){
//引用类型变量,传递的是地址,属于引用传递。
    str="test ok";
    ch[0]="g";
}

上面语句执行的时候,在栈中创建2个局部变量str,ch:

局部变量str被赋予A地址的副本,指向A地址.而局部变量ch被赋予地址B的副本,指向地址B.

当 str="test ok"; 执行的时候,我们知道地址A的内容是不会变的,那么即使局部变量str指向地址A,它的值变化也不会引起地址A中的值(即字符串常量的值)变化,而是在栈中开辟一个地址C,地址C中的值是“test ok”,局部变量str指向地址C,而成员变量str仍然指向地址A,且值是“tarena”.

当 ch[0]="g"; 执行的时候,由于地址B中的值可变,那么局部变量ch的值的变化,会导致地址B中的值的变化,地址B中第一个值就从"a"变为"g",因此成员变量ch指向地址B,它的值也变化["g","b","c"].

本题关键:理解不同类型引用的值是否可变.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值