美文网首页
基础打的好 源码难不倒

基础打的好 源码难不倒

作者: 码思客 | 来源:发表于2018-08-01 23:08 被阅读0次

    java零基础入门-面向对象篇(六)  String 字符串

    介绍完类和对象再来说String会轻松很多,因为String比较特殊,它是引用类型,但是又与普通的引用类型有点区别。看过很多其他介绍String的书籍,简单的把API讲一遍就草草了事,其实String这个类里面大有文章,理解好这个类,不仅可以对java的运行有更多了解,还可以了解更多的JVM有关细节,做到知其然,知其所以然,对我们今后更深入的了解java有莫大的好处。

    我会教大家看api的方法,其他自己去实践即可,体力劳动。

    什么是 API

    API : Application Programming Interface , 应用程序接口。光看名字肯定一头雾水,看图更有效

    java8 api 文档链接,英语不好的同学请配合百度翻译使用

    API使用方法

    我们查到了String有一个方法是charAt方法,他有一个参数是int类型,描述是返回下标所在处的字符。

    使用方法

    String的构造方法 和 字符串的比较

    为什么说字符串特殊?因为它既可以像普通数据类型一样初始化也可以像对象一样初始化

    字符串初始化

    字符串有很多构造方法,这里展示最常用的两个方法。两个不同的方式创建了两个都叫 “hello” 的字符串,但是在我们比较这两个字符串的时候,会出现一个问题,那就是比较的方式不同,得到了不同的结果。

    当我们使用 “ == ” 双等号比较两个字符串的时候,返回的结果是false,而当我们使用String的 “equals” 方法的时候,我们得到的是true。这是为什么呢?

    首先我们来确认以下几个定义,再复习一下前面的知识点,最后得出结论。温故知新是最好的学习方法。

    1.String 是类,不管通过那种方式构造出来的字符串都是String类的对象

    2.对象是引用类型,对象里面的值是地址

    3.==  双等号比较的是对象的地址

    4. 像基本类型一样初始化的字符串在内存中存放的位置与通过new构造出来的字符串存放的位置不同

    通过1,2,3点我们可以发现,如果两个字符串的地址是一样的,那么使用 == 比较返回的就是true,反之是false。这里主要的问题是4,你要好好理解两个不同的创建方式,字符串的位置是不同的。下面来详细说明第4点。

    jvm 堆,常量池

    写了这么多文章,发现在座的各位还是对房子最感兴趣,这次我们继续讲jvm这个开发商吧。(传送门 堆栈 jvm 太难懂?买房子总能理解了吧

    常量池

    我们前面说了,堆是商业区,就是大商场,大商场肯定会有很多层,堆里面也分为很多区域,这次我们先介绍一个区域,就是常量池。堆是用来放各种对象实例的,常量池也是一样,但是他有自己的特点。

    常量池在存对象的时候,会首先观察一下是否已经存在需要创建的对象。比如我们上面的 stringTest 保存的hello,它进去的时候,常量池里面是空的,所以划分一个空间,来保存hello这个字符串,但是当 stringTest2 再来的时候,他看到前面已经有一个hello了,他会直接将这个已存在的hello的地址,复制到自己的对象里面去,那么stringTest 和 stringTest2 其实是用的一个对象,他们的地址是一样的,他们指向同一个对象。

    这时候stringTest3也来了,但是他是 world 这个字符串,这时候的常量池里面只有 hello 这个字符串,他捡不到现成的,没办法,老实干活,自己开个空间吧,把world丢进去。

    上面的是直接用双引号 “” 来创建字符串的过程,下面来看用 new 关键字来创建字符串的过程。

    new 这个关键字很霸道,他就像是被宠坏的熊孩子,是不跟你讲道理的,只要用new 创建的,他都会在堆里面新开一个空间,所以不管我们new 创建的字符串是否内容一样,它都会有自己独立的空间,变量指向不同的地址。

    解释到这里,我们再看上面的第4点,是不是感觉茅塞顿开了?

    用双引号创建的字符串和用new创建的字符串根本就不在一层楼里面,你用双等号去比较地址肯定返回false。就算他们创建的都是 hello 这个字符串,也是一样,双等号比较的是地址不是内容,请记住这个。

    下面有个equals返回的是true,那么equals是干啥的?除了查API,我们还可以看源码~

    不要觉得看源码深不可测,其实我们只要掌握了前面的知识,源码看起来并没有那么难。

    查看源码的方法

    使用eclipse工具写代码的时候,可以按住ctrl键不动,再点击我们想要查看的方法,比如按住ctrl键不动,鼠标点击equals方法,再按照下面的方法做,就可以看到源码了。

    查看源码的方法

    按照我们上面的方法,已经可以打开源码了,我们来看看equals方法的源码吧

    equals方法源码解析

    我们看一段代码,一定要把思路理清楚,先做什么后做什么,我们看equals的思路是这样的

    1.首先比较调用者和参数 这2个字符串的地址,如果地址一样,则内容肯定一样,直接返回true

    2.然后将2个字符串转换为字符数组,因为转为了数组,可以取出字符串中每个字符进行比较

    3.循环遍历2个字符串数组,逐一比较每个位置上的字符,一旦有一个位置上的字符不同,则返回false

    4.如果全部比对完,而且每个位置上的字符都相同,则返回true

    到这里,我们就知道了 equals 方法是用来比较字符串里面的内容,所以不管这个字符串是怎么初始化出来的,不管他在内存中的什么位置,只要他们的内容一样,就是是相同的字符,则返回true。比如 “hello” 和 “hello”,每个字符都相同,则返回true。

    上面这个有两个迭代变量的循环,初学者看起来可能有点困难,我们可以用前面的方法,将每一步的循环写出来,这样理解起来方便很多

    循环步骤

    我们看到,从头到尾,每个位置上的字符都相同。

    其实这段源码里面的知识点,我前面都有说到,只要真的掌握好了,其实看起来也没有那么难。

    补充知识

    我们上面说常量池在jvm的堆里面,那是比较老的版本,新版本的jvm已经将常量池迁移到方法区了,就是我们前面说的那个大草地。因为堆里面存的对象实例太多,就会牵涉到一个问题,那就是垃圾回收,垃圾太多,清洁工阿姨工作太辛苦,工作就不开心了,所以jvm要减少他的工作压力,不断的优化垃圾回收机制。有兴趣的同学可以自行查阅相关资料,这部分知识并不是初学者需要掌握的知识,所以我们了解即可。

    相关文章

      网友评论

          本文标题:基础打的好 源码难不倒

          本文链接:https://www.haomeiwen.com/subject/yrftmftx.html