今天不知道怎么看了下string的==的问题,本身我觉得我这个水平去判断几个字符串相等还能出问题?呵呵,真的出了大问题,根本原因在于对java字节码的不了解。

首先,==运算符比较的是两个变量所指向的对象内存地址是否相同,相同则为true,不同则为false,因此问题变为分析字符串的内存地址是否相同;

(1)堆中的字符串对象和字符串常量池中的字符串

String s1 = "a";
String s2 = new String("a");
System.out.println(s1==s2);

结果为:false

原因:s1这种声明方式会在字符串常量池中新增一个“a”字符串对象,s2的声明方式则会在堆中创建一个"a"字符串对象;因此它们的内存地址并不同。

(2)堆中的两个字符串对象

String s1 = new String("a");
String s2 = new String("a");
System.out.println(s1==s2);

结果为:false

原因:两个不同对象的内存地址肯定不同。

(3)两个常量池中的字符串

String s1 = "a";
String s2 = "a";
System.out.println(s1==s2);

结果为:true

原因:字符串常量池的设计是这样:当往常量池中添加字符串时会先去判断是否已经有了此字符串,判断的方式为equals;因此s1、s2是引用的同一个字符串,内存地址相同。

(4)string.intern()方法

String s1 = "a";
String s2 = new String("a").intern();
System.out.println(s1==s2);

结果为:true

原因:intern方法会将字符串对象放入到常量池中,因此同(4)。

(5)变量和字符串相加

String s1 = "a";
String s2 = "b";
String s3 = "ab";
String s4 = s1+s2;
System.out.println(s3==s4);

结果为:false

原因:当对变量而不是字符串进行相加时,由于只知道字符串引用不知道具体的字符串值,jvm实际上是用StringBuilder的append方法完成的加操作,然后通过toString方法返回字符串的值,toString方法如下:

public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}

因此,原因同(1)。

情况还有就不列举了,只要去看java字节码就能明白为什么是这种情况,说到底,这些除了能帮助人理解java内存模型,其他什么用都没有,哦不,还能装逼。

java中String字符串的==解析的更多相关文章

  1. JAVA中String(字符串)课堂总结

    一:Java编译器中关于字符串自动优化 例子一: 源代码: public class StringPool { public static void main(String args[]) { Str ...

  2. Java中String字符串常量池总结

    最近到广州某建站互联网公司面试,当时面试官问假设有两个字符串String a="abc",String b = "abc";问输出a==b是true还是fals ...

  3. Java中String字符串常量池

    首先看一个例子,通过这个例子更能快速理解String常量池 public static void main(String[] args) { String a = "ab"; St ...

  4. java中String字符串

    一.定义String字符串 String字符串和char字符不同,char使用单引号,只能表示一个字符,字符串就是一段文本.String是个类.这个类使用final修饰,所以这个类是不可以继承扩充和修 ...

  5. java中String字符串的替换函数:replace与replaceAll的区别

    例如有如下x的字符串 String x = "[kllkklk\\kk\\kllkk]";要将里面的“kk”替换为++,可以使用两种方法得到相同的结果 replace(CharSe ...

  6. Java中String字符串toString()、String.valueOf()、String强转、+ ""的区别

    Object#toString(): Object object = getObject(); System.out.println(object.toString()); 在这种使用方法中,因为ja ...

  7. JAVA中String字符串比较equals()和equalsIgnoreCase()的区别

    标签: equals和equalsIgnoreC 2012-11-11 16:03 65644人阅读 评论(0) 收藏 举报  分类: JAVA(3)  1.使用equals( )方法比较两个字符串是 ...

  8. Java中的字符串操作(比较String,StringBuiler和StringBuffer)

    一.前言 刚开始学习Java时,作为只会C语言的小白,就为其中的字符串操作而感到震撼.相比之下,C语言在字节数组中保存一个结尾的\0去表示字符串,想实现字符串拼接,还需要调用strcpy库函数或者自己 ...

  9. Java中的字符串常量池

    ava中字符串对象创建有两种形式,一种为字面量形式,如String str = "droid";,另一种就是使用new这种标准的构造对象的方法,如String str = new ...

随机推荐

  1. yum clear all无反应

    卸载重装yum 操作系统版本:centos7 [root@linux-node3 ~]# uname -r 3.10.0-514.el7.x86_64 一.将现有的yum源卸载 [root@linux ...

  2. 元素定位(d4-2)

    一,元素定位①优先级:首先选择id,其次选class,再就是根据其他唯一元素,在更加层级过滤定位,根据多属性定位,②首选CSS定位,在选XPATH定位 1.xpath定位 //*   获取当前网页全部 ...

  3. web测试注意点

    关于网页测试我们需要注意的地方有: 1.每次测试之前都需要代码更新.清理缓存,测试数据使用新数据. 2.各模块的信息归类是否正确.比如进入一级栏目或二级栏目的列表页,查看左侧栏目名称,右侧文章标题及内 ...

  4. Jmeter学习系列----2 录制脚本

    虽然专业的自动化测试人员都不会选择录制脚本的方式来进行自动化脚本的编写,但是,我们作为初学者还是可以学习一下怎么利用工具来进行脚本的录制,体验一下自动化工具的效率,下面,具体讲下如何使用jmeter自 ...

  5. React(五)State属性

    React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM). 以下实例创建一个名称扩展为 React.Component 的 ES6 类,在 rende ...

  6. 输入、输出与Mad Libs 游戏

    name1=input('请输入一个名字:') name2=input('再输入一个名字:') time1=input('请输入一段时间:') print('{},是傻子,{},{}找不到小栗旬'.f ...

  7. STL--set_difference

    set_difference(),作用是求两个集合的差.即求A-B(属于A但不属于B的元素) set_difference()算法计算两个集合[start1, end1)和[start2, end2) ...

  8. 使用ngnix做服务器的负载均衡

    (1)  进程数与每个进程的最大连接数: nginx进程数,建议设置为等于CPU总核心数 单个进程最大连接数,那么该服务器的最大连接数=连接数*进程数 (2) Ngnix的基本配置 监听端口一般都为h ...

  9. Java 中 AOP —— 探讨其存在价值及实现方式对比

    AOP 概述 Aspect-oriented programming(面向切面编程).最广为人知的面向侧面的程序设计语言是由施乐帕洛阿尔托研究中心 (施乐帕克 nb!)开发的AspectJ,该语言可以 ...

  10. 蓝桥杯-加法变乘法(java)

    蓝桥杯第六届省赛题目-加法变乘法(java) 题目: 我们都知道:1+2+3+ ... + 49 = 1225 现在要求你把其中两个不相邻的加号变成乘号,使得结果为2015 比如: 1+2+3+... ...