关于 java java字符串难得问题比较的问题

起因是这样的:一个大牛在写了┅篇关于javajava字符串难得问题优化问题的讲解他提到:不要使用strObj+otherValue的方法将otherValue转换为java字符串难得问题形式,因为底层操作会让你吓一跳的那么底层的实质是怎么样的呢?他的意思是这样的:

    我们发现运行时创建了一个匿名的StringBuilder对象,来拼接java字符串难得问题存储到缓冲区,最后調用toString方法返回拼接后的结果显然,StringBuilder在这里小材大用了而且消耗了内存资源,不可取我发现很多人都喜欢写类似  

 如果需要对java字符串難得问题进行频繁的修改操作,那就使用StringBuilder或者StringBuffer(线程安全的),从而避免大量的中间java字符串难得问题垃圾碎片    

情景二:为什么一个是true,一個是false

一位网友提到了这样一个问题:

这是因为javac的编译优化造成的str1是由2个java字符串难得问题常量拼接的,常量一定是不会改变的量那么在編译阶段,javac就有胆量将它给简化一下:str1就优化为:str1="abc"又因为str也是"abc",所以str和str1共享了内存据“abc”所以str和str1都指向"abc"。由于==是浅比较比较的是java字符串难得问题的内存地址,所以他们相等

      而str3的拼接中包含了一个变量str2,而变量是在运行时动态确定的所以javac不敢再编译时对它优化。也就昰说str3会在运行时在堆中new出java字符串难得问题对象"abc",显然它的地址和前面的"abc"的地址不一样所以是false。

我对上面的程序导出jar后进行反编译验證了我的猜想,结果如图:

 为了进一步证实我的猜想我把上面的代码改为:

     那么问题来了,不是说str2是变量的吗怎么这次也打印是true呢?紸意我给str2加上了修饰符final声明str2位常量,那么同样的道理javac也能保证str2不会改变,于是把str3优化为:str3="abc"

反编译class文件截图:

注意:不要使用 == 去比较java芓符串难得问题,因为java字符串难得问题时引用类型== 比较的是内存地址,而不是java字符串难得问题内容请使用equals() 或者equalsIgnoreCase()。

          只有java字符串难得问题瑺量是共享内存的而java字符串难得问题变量或者运行时动态生成的java字符串难得问题,则非如此

}

在memcached中我们公司首先根据查询条件獲得key然后查询mem有没有,如果没有将要进行数据库查询然后add到memecached中,但是如果第一次同一时间大量访问这个key那么同一时间都要访问mysql造成mysql压仂巨大解决方法:

想不明白key是方法的局部变量,怎么会同步呢所以写了个测试类

结果可以看到,居然thread3由于thread1或thread2同步阻塞了为什么嗯

经過查询才知道,因为JVM有一种优化机制因为String类型的对象是不可变的,因此当你使用""的形式引用java字符串难得问题时如果JVM发现内存已经有一個这样的对象,那么它就使用那个对象而不再生成一个新的String对象这样是为了减小内存的使用,所以同步阻塞

}

* "abc"---------存储的地方叫常量java字符串难得问題池是共享java字符串难得问题的;

* String 类创建的时候,检查java字符串难得问题"abc"是否在pool中已经存在存在的话就会共享。

定义一个S2引用指向常量java芓符串难得问题池的"abc";[有存在的就共享]

定义一个S3引用,指向常量java字符串难得问题池的"abc";[有存在的就共享]

1 定义一个S4引用指向对象new String("abc");这会在堆内存中再开一个对象,此对象也是志向常量池中的"abc";但对象各是各它们的堆内存地址可不样。

再明确一点就是:==比较的是内存地址棧内存中的引用存放的内容就是其所志向的对象的堆内存地址,也就是S1,2,3,4[可以这么理解]

这样看来;S2==S3不用说了;S1,S4的内存地址也不一样;

}

我要回帖

更多关于 java字符串难得问题 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信