前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基础打的好 源码难不倒

基础打的好 源码难不倒

作者头像
用户5745563
发布2019-07-04 11:44:01
3590
发布2019-07-04 11:44:01
举报
文章被收录于专栏:码思客码思客
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要减少他的工作压力,不断的优化垃圾回收机制。有兴趣的同学可以自行查阅相关资料,这部分知识并不是初学者需要掌握的知识,所以我们了解即可。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-08-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码思客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档