返回信息流想请教一下:
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
这是一条镜像帖。来源:北邮人论坛 / java / #39609同步于 2015/3/30
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
关于字符串相等的判断
Jungle
2015/3/30镜像同步13 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
所以判断字符串相等要用.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" );
: ...................
【 在 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]
=.=不知道,不过感觉一般不会用到
【 在 Jungle 的大作中提到: 】
: 感谢大神回答,稍微懂了一点。我提的这个问题是不是有点钻牛角尖呀,需要掌握不,本人小白
==比较的是引用,.equals比较的是内容,你换成后者试试
【 在 Jungle (Jungle) 的大作中提到: 】
: 感谢大神回答,稍微懂了一点。我提的这个问题是不是有点钻牛角尖呀,需要掌握不,本人小白[ema21]
通过『我邮2.0』发布
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。参见源码:
: ...................
字节码来看,编译以后第一个就是println(true).
至于编译器里根据什么做这个优化就不知道了。
【 在 axpq110 的大作中提到: 】
: System.out.println("a"+"b" == "ab" );
: System.out.println( "a"+"b".toLowerCase() == "ab" );
: 可是上面这俩第一个true第二个false很想不通啊
: ...................
来自「北邮人论坛手机版」
编译器优化的问题
编译器在遇到代码里两个常量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很想不通啊
: ...................