字符串之间 == 与 euqals 的问题

不啃不舒服斯基 2010-01-07 06:46:35
“==”判断的是内存地址,而equals可被重写。这句话没大问题吧。
我的一个Servlet:
	protected void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String action = request.getParameter("action");
if (action.equals( "aa"))
System.out.println("aaaaaaaa"); }


然后,在浏览器里传个参数aa,action.equals("aa")为true,但 action.=="aa" 就为false,请高人讲下详细原因。
...全文
272 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
banleihncj 2010-01-15
  • 打赏
  • 举报
回复
都解决了还要什么分,
dinghun8leech 2010-01-15
  • 打赏
  • 举报
回复
这是描述Java编译器对字符串常量的优化方法。 
众所周知,数据内容是要定义在数据段的,假设下面的代码:
String s1 = "abc" ;
String s2 = "abc" ;
假如不进行优化的话,结果就是内存中有两个重复的"abc"内容,也就是说有两个“对象”。
Java编译器会针对这种情况进行优化,对于常量字符串"abc",java编译器会只产生一个"abc"对象。这样,s1和s2是指向同一个内存区域的。

但假如字符串的值无法在编译时确定,如:String g = a.concat("3");
那么Java编译器将会为g变量分配一个空间。注意也不是立即分配,因为Java编译器是在全局对动态分配内存。

补充: 编译器不会检查 "test" + "3" 的结果是否就是"test3",因此创建新对象。

和编译期拼接 值未知、编译器不检查拼接结果有关,与final无关。。。。
BearKin 2010-01-15
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 dinghun8leech 的回复:]
Java code// 至于S5么..LZ你猜? > <真逗
我猜对了,不过也有点疑惑,s3+s4的值确实和s1一样,难道jvm就不能拿这个值上StringPool里找一下吗,找到了传回个地址不就完了?何必再另开一块内存存个和s1的值一样的字符串。。。。
[/Quote]

final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final final
dinghun8leech 2010-01-15
  • 打赏
  • 举报
回复
// 至于S5么..LZ你猜? > <
真逗
我猜对了,不过也有点疑惑,s3+s4的值确实和s1一样,难道jvm就不能拿这个值上StringPool里找一下吗,找到了传回个地址不就完了?何必再另开一块内存存个和s1的值一样的字符串。。。。
BearKin 2010-01-15
  • 打赏
  • 举报
回复
LZ可否把分结了...
TzSword 2010-01-11
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 bearkin 的回复:]
恩  老竹子讲过很多次这个问题 首先我给LZ几行代码 LZ运行过后就明白了(不象LS那几位想象的那样 貌似吧..)

Java codepackage heap;publicclass Test {publicstaticvoid main(String[] args) {
String s1="你好LZ";
String s2="你好LZ";
String s3="你好";
String s4="LZ";
String s5= s3+ s4;// 两个String使用常量池相同的地址 因为'你好LZ'这几个字已经存在了// JAVA为了节约内存,相同内容的String(名字不同)其实可能会指向同一块内存(同一个引用)// 所以s2实际上是使用s1已经创建过的字符串// 但是s3 和 s4分别是两个不同的字符串 创建他们的同时也就是创建了两个内存 所以==会失败// 至于S5么..LZ你猜? > < System.out.println(s1== s2);
System.out.println(s1== (s3+ s4));
System.out.println(s1== s5);
System.out.println("-------------------------------------------------");// 至于值比较嘛。。。当然都一样了。。 System.out.println(s1.trim().equals(s2));
System.out.println(s2.trim().equals(s3+ s4));
System.out.println(s2.trim().equals(s5));
}
}

时代久远 也许错了.. 楼下指正..
[/Quote]

有代码就有真相了。。。。。。。。哈哈。。。。
feitian124 2010-01-11
  • 打赏
  • 举报
回复
mark
Select9 2010-01-08
  • 打赏
  • 举报
回复
对于字符串来说 eques是比较的字符串内容
而"=="比较的是基本类型的相等性或者对象是否是同一个引用(同一个对象)
BearKin 2010-01-08
  • 打赏
  • 举报
回复
恩 老竹子讲过很多次这个问题 首先我给LZ几行代码 LZ运行过后就明白了(不象LS那几位想象的那样 貌似吧..)


package heap;

public class Test {
public static void main(String[] args) {
String s1 = "你好LZ";
String s2 = "你好LZ";
String s3 = "你好";
String s4 = "LZ";
String s5 = s3 + s4;
// 两个String使用常量池相同的地址 因为'你好LZ'这几个字已经存在了
// JAVA为了节约内存,相同内容的String(名字不同)其实可能会指向同一块内存(同一个引用)
// 所以s2实际上是使用s1已经创建过的字符串
// 但是s3 和 s4分别是两个不同的字符串 创建他们的同时也就是创建了两个内存 所以==会失败
// 至于S5么..LZ你猜? > <
System.out.println(s1 == s2);
System.out.println(s1 == (s3 + s4));
System.out.println(s1 == s5);
System.out.println("-------------------------------------------------");
// 至于值比较嘛。。。当然都一样了。。
System.out.println(s1.trim().equals(s2));
System.out.println(s2.trim().equals(s3 + s4));
System.out.println(s2.trim().equals(s5));
}
}



时代久远 也许错了.. 楼下指正..
Dazzlingwinter 2010-01-08
  • 打赏
  • 举报
回复
3.6.5 检测字符串是否相等
可以使用equals方法检测两个字符串是否相等。
如果字符串s与字符串t相等,则表达式s.equals(t)返回true;
否则返回false。
需要注意,s与t可以是字符串变量,也可以使字符串常量。
一定不能使用==运算符检测两个字符串是否相等!
这个运算符只能够确定两个字符串是否被放置在同一个位置。
当然,如果字符串放在同一个位置,他们必然相等。
但是,完全有可能将内容相同的两个字符串放在不同的位置上。
如果虚拟机总是将相同的字符串共享,就可以使用==运算符检测是否相等。
但实际上只有字符串常量是共享的,而+或substring等操作产生的结果都不是共享的。
因此,永远都不要使用==运算符的测试字符串的相等性,否则在程序中会出现很糟糕的bug,从表面上看很像随机产生的间歇性错误!
From《Java2核心技术第七版卷I,基础知识,Page49》
Johnson_Hong 2010-01-08
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 crazylaa 的回复:]
引用 2 楼 johnson_hong 的回复:
哪里有问题呢
action.equals("aa")肯定是true
action=="aa"为false也正常啊,是2个不同对象啊

如果定义一个static final String AA="aa";
action.equals(AA)
action==AA
这个时候应该都true了吧?
[/Quote]

equal的对象当然也有==为true的,也有==为flase的,这和jdk常量池的机制有关,楼主的这里==为false也没有什么奇怪的,因为楼主这里是2个不同对象.
JavaAlpha 2010-01-08
  • 打赏
  • 举报
回复
风云乍起 2010-01-08
  • 打赏
  • 举报
回复
String类型用==在java中进行比较是对象的比较,也就是指两个对象是否为同一个(相等),如果用equals的话,是比较两个对象的值是否相等……
wsw0125 2010-01-08
  • 打赏
  • 举报
回复
哪里有问题呢
action.equals("aa")肯定是true
action=="aa"为false也正常啊,是2个不同对象啊

不错
cnm20091 2010-01-08
  • 打赏
  • 举报
回复
public class EqualsTest {
private static final String str1 = "AA";


public static void main(String[] args) {
System.out.println(str1.equals(getAA()));
System.out.println(str1 == getAA());
}

public static String getAA() {
return "AA";
}

}


true
true
wydhao123 2010-01-08
  • 打赏
  • 举报
回复
crazylaa 2010-01-08
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 johnson_hong 的回复:]
哪里有问题呢
action.equals("aa")肯定是true
action=="aa"为false也正常啊,是2个不同对象啊
[/Quote]
如果定义一个static final String AA="aa";
action.equals(AA)
action==AA
这个时候应该都true了吧?
crazylaa 2010-01-08
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 johnson_hong 的回复:]
哪里有问题呢
action.equals("aa")肯定是true
action=="aa"为false也正常啊,是2个不同对象啊
[/Quote]
94
hbu_zhy 2010-01-08
  • 打赏
  • 举报
回复
同意3L
Java&Oracle学习交流群,知无不言,言无不尽。欢迎大家交流分享学习工作心得。QQ群:20378027
清风水岸 2010-01-08
  • 打赏
  • 举报
回复
跟我原来的疑问一样。呵呵
加载更多回复(6)

67,512

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧