String.intern()详解,关于String s2 = new String("ja") + new String("va"); s2.intern();

String.intern()详解,关于String s2 = newString("ja") + new String("va");     s2.intern();

写这篇文章的情况是在看面试题的时候遇到了一些疑问,查看了好多大神的文章,总算有了一些理解,为了记忆,整理了一下。

首先看一下面试题

	public static void m1(){
		String s1 = new StringBuilder("go").append("od").toString();
		System.out.println(s1.intern() == s1);
		String s2 = new StringBuilder("ja").append("va").toString();
		System.out.println(s2.intern() == s2);
	}
	public static void main(String[] args) {
		m1();
	}

输出结果:

true

false

当时直接懵逼了,为什么同样的方式,结果为什么不一样。测试发现问题出在java这个字符串上。

百度,学习了https://www.zhihu.com/question/51102308中的一些知识,发现原来是在JVM启动的时候调用了一些方法,在常量池中已经生成了"java"字符串常量,所以才会有所不同。

到这里我还是迷迷糊糊的,这和字符串常量啥关系呀。急的我是抓耳挠腮,继续百度,发现了一个大神,SEU_Calvin的一篇博客,http://blog.csdn.net/seu_calvin/article/details/52291082

我把这道面试题给改了一下:

public static void main(String[] args) {
		m6();
	}
	public static void m6(){
		String s1 = new String("go") + new String("od");
		s1.intern();
		String s3 = "good";
		System.out.println(s1 == s3);
		
		String s2 = new String("ja") + new String("va");
		s2.intern();
		String s4 = "java";
		System.out.println(s2 == s4);
	}

输出结果:

true

false

继续测试

public static void main(String[] args) {
		m6();
	}
	public static void m6(){
		String s1 = new String("good");
		s1.intern();
		String s3 = "good";
		System.out.println(s1 == s3);
	}

发现结果成:false

问题出在哪呢,虽然看了大神的博客,但是还是有一些疑问。我又 参考了自己之前写的一篇博客。我先把大神的图拿过来


看了有些不明白,为了图省事我手动修改了一下


为什么这么改呢,先看下面大神给出的过程。

String s = newString("1"),生成了常量池中的“1”和堆空间中的字符串对象

s.intern(),这一行的作用是s对象去常量池中寻找后发现"1"已经存在于常量池中了

String s2 = "1",这行代码是生成一个s2的引用指向常量池中的“1”对象

结果就是 s 和 s2 的引用地址明显不同。因此返回了false。

 

String s3 = new String("1")+ newString("1"),这行代码在字符串常量池中生成“1”,并在堆空间中生成s3引用指向的对象(内容为"11")。注意此时常量池中是没有 “11”对象的。

s3.intern(),这一行代码,是将 s3中的“11”字符串放入 String常量池中,此时常量池中不存在“11”字符串,JDK1.6的做法是直接在常量池中生成一个 "11" 的对象。

但是在JDK1.7中,常量池中不需要再存储一份对象了,可以直接存储堆中的引用。这份引用直接指向s3引用的对象也就是说s3.intern() ==s3会返回true。

String s4 = "11", 这一行代码会直接去常量池中创建,但是发现已经有这个对象了,此时也就是指向s3引用对象的一个引用。因此s3 == s4返回了true

 

重点在


到这里,我总算弄明白了,当浮一大白!

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值