我们知道,在java的源码中,String是由final修饰的。
说明String变量一旦创建,便不可以修改。
例如这样:
public class POP { public static void main(String[] args) { String a = "111"; } }
你可以尝试在idea中通过a.的方法来看是否能调用来指定更改某个位子的1的方法。
或者在string api中寻找是否有相关方法。
其实并不存在能通过索引修改某个string某位子的方法。
不过你能找到几个用于替换字符的方法。
为什么不提供呢?
因为没有意义。
你可以尝试运行下列代码:
public class POP { public static void main(String[] args) { String a = "111"; String b = "111"; System.out.println(a==b);//true } }
输出的结果是true。
我们知道,引用类型的变量,存储的是对象的地址值,难道a和b的地址值还能一样吗?
是的。
他们的地址值一样,都位于java的常量池中。
常量池专门用于管理编译时被确定并被保存在已编译的字节码文件中的一些数据,他包括了关于类、方法、接口中的常量、还包括字符串常量。
如果你想了解更多JVM相关的信息,可以关注我的JVM专栏。
这也是为什么,此前的a和b的地址值相等的原因。
因为常量池中建立了111这个字符串,b在创建的时候,会先在常量池查找看看有没有相同的,如果有,则直接指向它。
public class POP { public static void main(String[] args) { String a = "111"; String c = "11" + "1"; System.out.println(a==c);//true } }
这种情况下也是true,因为c在编译时也能确认他在哪。
可能看到这里会有点奇怪,我之前说了String对象放在常量池中,为什么现在我又说它在堆中呢?
可以看以下代码:
public class POP { public static void main(String[] args) { String a = "111"; String b = new String("111"); System.out.println(a==b);//false } }
你会发现,它的输出结果是false,这是为什么呢?
为什么通过new来创建的字符串,他们的地址值就不同了呢?
因为b的操作是,现在堆空间中创建对象,再把对象的string值指向常量池的111。
而我比较的==,比较的是变量a和变量b的地址值,a的地址值指向常量池的值,b的地址值指向堆空间的对象,这当然不对了。
那,是不是只有new出来的对象在堆空间呢?
也不是,之前我说过,常量池只存放编译时能确认的string对象,如果编译时不能确认,那就创建在堆空间中。
我们之前发现了string api中有部分修改string的方法,而我之前说过string是一个不可变类,那他为什么又能去修改呢?
因为,在我们修改完成后,我们并未在原String的值上进行修改,而是在常量池中查找是否存在我们修改后的这个值,如果没有,我们就在常量池之中新建一个。
那么你怎样才能得到这个新的更改值呢?
你可以看到,这个方法的返回值是String,你可以把它的地址值返回给你想给的string变量。
那么说了这么多,你应该对这个也有了解了吧?
那不如来看看下列代码,看你能不能解释清楚原理呢?
public class POP { public static void main(String[] args) { String a = "111"; String b = new String("111"); System.out.println(a==b);//false String c = "11" + 1; System.out.println(a==c);//true String d = "1" + "11"; System.out.println(c==d);//true String e = a;//地址赋予 System.out.println(a==e);//true String temp1 = "11"; String temp2 = "1"; String f = temp1 +"1"; String g = temp1 + 1; String h = temp1 + "1"; System.out.println(f==g);//false System.out.println(f==h);//false String i = 11 + temp2; System.out.println(f==i);//false String j = temp1 + temp2; System.out.println(f==j);//false } }
如果存在不是很清楚的地方,欢迎在下方评论。