咱们再来看一段代码:java
运行一下:post
没错,一个true,一个是false,(答错的小朋友去面壁去),你们可能在想编译器确定又调皮了,编译的时候是否是又偷偷加了些什么,火烧眉毛的打开class文件看一下:3d
除了删掉了空行之外和个人java源文件一致呀,这回可冤枉编译器了,那为何会致使不一样的结果呢?咱们都知道,Java代码是运行在JVM里的,那是否是JVM在执行这段代码时给咱们作了什么?
在JVM中,当代码执行到String s1 = "100" 时,会先看常量池里有没有字符串恰好是“100”这个对象,若是没有,在常量池里建立初始化该对象,并把引用指向它,以下图,绿色部分为常量池,存在于堆内存中。cdn
当执行到String s2 = "100" 时,发现常量池已经有了100这个值,因而再也不在常量池中建立这个对象,而是把引用直接指向了该对象,以下图:对象
这时候咱们打印System.out.println(s1 == s2)时,因为==是判断两个对象是否指向同一个引用,因此这儿打印出来的就应该是true。
blog
继续执行到Strings3 = new String("100") 这时候咱们加了一个new关键字,这个关键字呢就是告诉JVM,你直接在堆内存里给我开辟一块新的内存,以下图所示:内存
继续执行String s4 = new String("100")字符串
这时候再打印System.out.println(s3 == s4) 那必定即是false了,由于s3和s4不是指向对一个引用(对象)。get
注:图中只是画出了main方法栈和相关对象在内存中的大体模拟,实际中JVM中内存管理比较复杂,你们有条件的话能够去找《Java虚拟机规范》这本书去深刻研究。
结论:咱们在比较两个String对象内容时,不管是怎么声明的,都必定要使用equals去比较,不能用==,在Java中没有重载操做符这一说,特别是从其它语言转到Java的童鞋们要注意。equals我会在后续专栏里已经作了详细解说。编译器
下一篇:说说Java里的equals(上) - Java那些事儿
若是喜欢本系列文章,请为我点赞或顺手分享,您的支持是我继续下去的动力,您也能够在评论区留言想了解的内容,有机会本专栏会作讲解,最后别忘了关注一下我。
转载无限欢迎,但请注明「做者」和「原文地址」。转载请在文中保留此段,感谢您对做者版权的尊重。如需商业转载或刊登,请联系做者得到受权。