zoukankan      html  css  js  c++  java
  • Java基础知识陷阱(一)

        本文发表于本人博客

        事隔好多年了,重新拿起来Java这门语言,看似熟悉其实还很陌生,想想应该梳理下顺便提高下自己。这次先来看看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);

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

        QQ图片20141203154106.jpg

    看到这个图片,相信就知道那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

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

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

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

        true
        false

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


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


  • 相关阅读:
    设计模式 享元模式(池化技术)
    设计模式 混合模式(整体部分模式)
    设计模式 适配器模式
    Flex3示例、 安装 、注册码
    VS2010错误
    转载:glut.h 与 stdlib.h中 的exit()重定义问题的解决
    宿迁软件QQ群(109233721)
    百度地图 开发API接口啦
    Sublime Text 插件个人使用总结&推荐
    sublime text2 使用安装插件中文乱码问题解决
  • 原文地址:https://www.cnblogs.com/luoliang/p/4140339.html
Copyright © 2011-2022 走看看