java——String的那边破事

经典的先看下面一段代码,请问最终创建几个对象,分别在哪里?

String s0 = new String("luoliang.me");
String s1 = "luoliang.me";
String s2 = new String("luoliang.me");

想要回答这个问题,先得搞清楚new String()以及String pool的,下面我慢慢来说下。

在java中所有的字符串都会保存在一个叫String pool字符串池里面,这里面的字符串都是有String类独立维护,过程是先判断存在这个字符串不,如果存在就不用创建,否则就在里面创建一个。

那new String("luoliang.me")这个呢,看到new关键字说明会创建对象,先回去字符串池找是否存在,不存在创建,完毕后会在堆中创建这个对象,记住这个对象也是字符串“luoliang.me”的,到这里大家差不多都知道了,那看下面:

String s0 = new String("luoliang.me");执行这句后,系统中会存在2个对象,一个是字符串池的"luoliang.me",另外一个是堆中的new String("luoliang.me"),最后把s0指向这个对象。

String s1 = "luoliang.me"; 执行这句话之后系统中不会增加对象,不变,原因是s1直接指向了字符串池的"luoliang.me"。

String s2 = new String("luoliang.me");执行这句之后,系统中增加一个对象,原因是在字符串池中已经存在"luoliang.me"这个不用创建,直接在堆里创建一个对象,并把s2指向这个对象。

最后总结执行3句之后:系统中存在3个对象,一个是在字符串池中,另外2个是在堆中。

下面接着来看看:

System.out.println(s0 == s1);
System.out.println(s0 == s2);
System.out.println(s1 == s2);

这个应该是比较简单了,在基本类型里面==直接比较的是其值,但是对象的话比较的是引用,就是地址的意思。下面我画一张图表示之前的代码在内存的情况:

看到这个图片,相信就知道那3个输出是什么了!都是false

这样说可能还有人不信,那么我们可以使用String的intern()方法(表示其字符串池中字符串的地址)来比较,看下面:

System.out.println(s0 == s0.intern());
System.out.println(s0.intern() == s1); System.out.println(s0.intern() == s2.intern());
System.out.println(s1 == s2.intern());

输出是:

false
true
true
true
  1. 下面我们来看看更有趣的,可能很多人想不到会是这样的结果。

    String luoliang = "luoliang";
    String luo = "luo";
    String liang = "liang";
    System.out.println(luoliang == "luo" + "liang");
    System.out.println(luoliang == "luo" + liang);System.out.println("luoliang" == luo + liang);

    问下输出的结果是什么,答案是:

  2. 问下输出的结果是什么,答案是:
  3. true
    false

    至于为什么吗,字面值常量相加等于直接相加然后在字符串池存储,而字面值跟变量相加堆在堆生成一个对象,这样可想而知地址是怎么样的了!

    这次先到这里。坚持记录点点滴滴!

参考:http://www.luoliang.me/index.php/archives/ProgrammingLanguage/35.html

时间: 2024-10-16 06:48:01

java——String的那边破事的相关文章

踩一坑,采一金之php数据类型那点“破”事

学海无涯,乘舟以渡之~ php边学边写差不多一年多点,php这种弱类型语言与之前接触的c.java.as3等语言还是挺不一样的,现在觉得很庆幸的是从c开始学编程,无论数据类型还是指针也好,至少有个基础的概念. 在php数据类型上踩了不少坑,也学到了一些东西,在这里分享一下,看源码可能会很枯燥,不过了解一些底层实现就好,后面不要再踩坑. 序. 之前在网上看到有比较热的帖子说:PHP的ip2long有bug,请慎用?于是看了下描述,大致如下 <?php echo ip2long('58.99.11.

扯一扯关于android开发工具的破事

一.前言 开发android一转眼之间已经过去一年多了,回想到以前刚开始学习android还是在大学里面,那是看了mars的视频教程就开始android之路,从最开始的环境搭建到开发项目,一步一步自己摸索进步,由于一直没有遇到资深的android工程师带领我,所以自己大部分学习来自于网络的blog,eoe论坛,所以我深爱技术分享这个东西,因为网络的强大是由于一大批人不为任何利益分享自己的技术,所以我们才能在网络上找到答案,就算没有答案也可以找到前人研究的成果,我们就可以踩着前人的肩膀继续前进,技

摘抄-----java codeReview要做的事

整洁的代码 清单项目 分类 使用可以表达实际意图(Intention-Revealing)的名称 有意义的名称 每一个概念只用一个词 有意义的名称 使用方案/问题领域名称 有意义的名称 类应该是比较小的! 类 函数应该是比较小的! 函数 只做一件事 函数 DRY(Don’t Repeat Yourself)原则,(拒绝重复) 函数 用代码来解释自己的做法(译者注:即代码注释) 注释 确定应用了代码格式化 格式 使用异常而不是返回码 异常 不要返回Null 异常 *参考自:http://techb

java String 类 基础笔记

字符串是一个特殊的对象. 字符串一旦初始化就不可以被改变. String s = "abc";//存放于字符串常量池,产生1个对象 String s1=new String("abc");//堆内存中new创建了一个String对象,产生2个对象 String类中的equals比较字符串中的内容. 常用方法: 一:获取 1.获取字符串中字符的个数(长度):length();方法. 2.根据位置获取字符:charAt(int index); 3.根据字符获取在字符串中

java开发中的那些事(5)--------一点经历,败给2分钟的2个小时

特意记下这个经历,这个让我感慨万千又斗志昂扬的一次经历,这是经验,也是生活. 故事的始末是这样的,先给大家上几句代码,现在身在家中,只能凭记忆敲打几行,大致意思倒不会错: {field:'code',align:'center'} {field:'btfid',align:'center',hidden:'true', formatter:function(value,row,rowIndex){ return "<a href="javascript:void(0)"

Java String字符串/==和equals区别,str。toCharAt(),getBytes,indexOf过滤存在字符,trim()/String与StringBuffer多线程安全/StringBuilder单线程—— 14.0

课程概要 String 字符串 String字符串常用方法 StringBuffer StringBuilder String字符串: 1.实例化String对象 直接赋值  String str="Hello";  推荐这种 使用关键字new  String str1=new String("Hello"); 在内存中开辟2个空间 如图: 源代码 StringDemo01.java 2.String内容的比较 String str="Hello"

java开发中的那些事(3)-------最常用到的几个快捷键

今天去看了韩寒的<后会无期>,感慨颇多. 这里记录下现在常会用到的几个快捷键,不多,却是当前最常用到: 1.ctrl+f  ----------------"搜索", 这个应该在大多数人来说都太简单了,可惜我也是知道不长时间: 2.ctrl+shift+r  --------"工程内搜索",这个也是搜索,不过是搜索整个工程的,这个知道后美滋滋了好久: 3.ctrl+/  ----------------"简单注释","//&

java String 两种不同的赋值 比较

原文http://blog.163.com/[email protected]/blog/static/1271436362012101214031911/ 在此感谢博主写出这么优秀的文章. 首先明确一点,String是一个类.下面我们主要讨论两个问题  a) String类的对象的两种赋值方式  b) 为什么String类的对象可以直接赋值  a) 1 类似普通对象,通过new创建字符串对象.String str = new String("Hello"); 内存图如下图所示,系统会

java string,需要进行首字母大写改写

java string,需要进行首字母大写改写,网上大家的思路基本一致,就是将首字母截取,转化成大写然后再串上后面的,类似如下代码 //首字母大写     public static String captureName(String name) {         name = name.substring(0, 1).toUpperCase() + name.substring(1);        return  name;           } 将字符串name 转化为首字母大写.但是