BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / java / #39609同步于 2015/3/30
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖

关于字符串相等的判断

Jungle
2015/3/30镜像同步13 回复
想请教一下: System.out.println("a" == "a"); System.out.println("a"+"b" == "ab" ); System.out.println("a".toLowerCase()=="a" ); System.out.println( "a"+"b".toLowerCase() == "ab" ); System.out.println("A".toLowerCase()=="a"); 结果分别是true true true false false
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
aiquestion机器人#1 · 2015/3/30
所以判断字符串相等要用.Equal(...)... jdk1.8反编译了一下,貌似System.out.println("a" == "a"); System.out.println("a"+"b" == "ab" );都没有比较的过程,应该是编译的时候直接运算过了。所以直接输出的true。 System.out.println("a".toLowerCase()=="a" ); 的toLowerCase方法,应该是没有大写字母就返回原String。参见源码: /* Now check if there are any characters that need to be changed. */ scan: { for (firstUpper = 0 ; firstUpper < len; ) { char c = value[firstUpper]; if ((c >= Character.MIN_HIGH_SURROGATE) && (c <= Character.MAX_HIGH_SURROGATE)) { int supplChar = codePointAt(firstUpper); if (supplChar != Character.toLowerCase(supplChar)) { break scan; } firstUpper += Character.charCount(supplChar); } else { if (c != Character.toLowerCase(c)) { break scan; } firstUpper++; } } return this; } 然后后两个因为toLowerCase和+会生成一个新的String,所以比较结果是false。 附用javap查看的。class文件结果: 0: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream; 3: iconst_1 4: invokevirtual #22 // Method java/io/PrintStream.println:(Z)V 7: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream; 10: iconst_1 11: invokevirtual #22 // Method java/io/PrintStream.println:(Z)V 14: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream; 17: ldc #28 // String a 19: invokevirtual #30 // Method java/lang/String.toLowerCase:()Ljava/lang/String; 22: ldc #28 // String a 24: if_acmpne 31 27: iconst_1 28: goto 32 31: iconst_0 32: invokevirtual #22 // Method java/io/PrintStream.println:(Z)V 35: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream; 38: new #36 // class java/lang/StringBuffer 41: dup 42: ldc #28 // String a 44: invokespecial #38 // Method java/lang/StringBuffer."<init>":(Ljava/lang/String;)V 47: ldc #41 // String b 49: invokevirtual #30 // Method java/lang/String.toLowerCase:()Ljava/lang/String; 52: invokevirtual #43 // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer; 55: invokevirtual #47 // Method java/lang/StringBuffer.toString:()Ljava/lang/String; 58: ldc #50 // String ab 60: if_acmpne 67 63: iconst_1 64: goto 68 67: iconst_0 68: invokevirtual #22 // Method java/io/PrintStream.println:(Z)V 71: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream; 74: ldc #52 // String A 76: invokevirtual #30 // Method java/lang/String.toLowerCase:()Ljava/lang/String; 79: ldc #28 // String a 81: if_acmpne 88 84: iconst_1 85: goto 89 88: iconst_0 89: invokevirtual #22 // Method java/io/PrintStream.println:(Z)V 92: return LineNumberTable: 【 在 Jungle 的大作中提到: 】 : 想请教一下: : System.out.println("a" == "a"); : System.out.println("a"+"b" == "ab" ); : ...................
Jungle机器人#2 · 2015/3/30
【 在 aiquestion 的大作中提到: 】 : 所以判断字符串相等要用.Equal(...)... : jdk1.8反编译了一下,貌似System.out.println("a" == "a"); System.out.println("a"+"b" == "ab" );都没有比较的过程,应该是编译的时候直接运算过了。所以直接输出的true。 : System.out.println("a".toLowerCase()=="a" ); 的toLowerCase方法,应该是没有大写字母就返回原String。参见源码: : ................... 感谢大神回答,稍微懂了一点。我提的这个问题是不是有点钻牛角尖呀,需要掌握不,本人小白[ema21]
aiquestion机器人#3 · 2015/3/30
=.=不知道,不过感觉一般不会用到 【 在 Jungle 的大作中提到: 】 : 感谢大神回答,稍微懂了一点。我提的这个问题是不是有点钻牛角尖呀,需要掌握不,本人小白
byrEE机器人#4 · 2015/3/30
==比较的是引用,.equals比较的是内容,你换成后者试试 【 在 Jungle (Jungle) 的大作中提到: 】 : 感谢大神回答,稍微懂了一点。我提的这个问题是不是有点钻牛角尖呀,需要掌握不,本人小白[ema21] 通过『我邮2.0』发布
icyfox机器人#5 · 2015/3/30
这个不是钻牛角尖而是经常会问到的问题所以你可以看看关于String的博客
W1039766642机器人#6 · 2015/3/30
java的字符串比较用的是equals(),你说的= =是比较的字符串的指向的地址是不是一样的。
axpq110机器人#7 · 2015/3/31
System.out.println("a"+"b" == "ab" ); System.out.println( "a"+"b".toLowerCase() == "ab" ); 可是上面这俩第一个true第二个false很想不通啊 【 在 aiquestion 的大作中提到: 】 : 所以判断字符串相等要用.Equal(...)... : jdk1.8反编译了一下,貌似System.out.println("a" == "a"); System.out.println("a"+"b" == "ab" );都没有比较的过程,应该是编译的时候直接运算过了。所以直接输出的true。 : System.out.println("a".toLowerCase()=="a" ); 的toLowerCase方法,应该是没有大写字母就返回原String。参见源码: : ...................
aiquestion机器人#8 · 2015/3/31
字节码来看,编译以后第一个就是println(true). 至于编译器里根据什么做这个优化就不知道了。 【 在 axpq110 的大作中提到: 】 : System.out.println("a"+"b" == "ab" ); : System.out.println( "a"+"b".toLowerCase() == "ab" ); : 可是上面这俩第一个true第二个false很想不通啊 : ................... 来自「北邮人论坛手机版」
dss886机器人#9 · 2015/3/31
编译器优化的问题 编译器在遇到代码里两个常量String相加时,会在编译期就加起来,在代码运行时实际的代码应该是System.out.println("ab" == "ab" ); 而String常量在常量池中只存在一份,所以前一个"ab"和后一个"ab"指向同一个对象,故返回True 而编译器并不会在编译期对String.toLowerCase()这个函数进行处理,在代码执行期间,"b".toLowerCase()返回"b",a+b返回ab,此时的ab是在代码运行期间被new出来的,存在与堆中,与后一个ab(存在于常量池中)指向的并不是同一个对象,故返回false 可以看看http://bbs.byr.cn/#!article/Java/38943这篇帖子里面的讨论 【 在 axpq110 的大作中提到: 】 : System.out.println("a"+"b" == "ab" ); : System.out.println( "a"+"b".toLowerCase() == "ab" ); : 可是上面这俩第一个true第二个false很想不通啊 : ...................