包装类 Wrapper

八大包装类继承体系图

 

虚线表示实现接口,实线表示继承父类。。。。。

包装类和基本数据类型的转换

基本数据类型不是对象,然而包装类是对象。。。。。

演示装箱和拆箱:

jdk5以前必须是手动:

 jdk5之后可以自动装箱和拆箱:

底层还是运用到的是valueof这个方法:

底层对这个inValue方法进行包装,debug追进去之后可以发现。

其他的包装类转换和这种类似,自己试一试

包装类练习:

经典面试题

三元运算符是一个整体,因此最高精度是double类型,因此当输出1的时候,会发生精度的提升,因此输出的是 1.0

这个if else是分别进行的,不是同一个整体。所以精度不会互相影响。。。

包装类转换为String类型

 方式1解释:一开始我们使用自动装箱,把100装进去,自动转换为Integer类型(但还是底层实现了valueOf方法)Integer.valueOf(100)。

之后我们加上一个空字符串,在字符串常量池合成一个新的字符串"100",但是原来的Integer类对象并没有发生任何的改变 还是 100这个对象。

valueOf源码:

String类型转换为包装类类型:

总结:

包装类常用方法

面试题

Integer m=1和Integer n=1两者很明显是自动装箱。那么我们知道,他们的本质还是调用包装类Integer的valueOf这个方法

阅读valueOf方法源码可知:范围为-128到127之间的时候,直接返回这个值。不在这个范围的时候,我们是返回这个new出的对象

结果:

1表示对 2表示错

2  2  1  2  2  1  1

记录:只要有基本数据类型,判断的就是值是否相同。一旦出现了一个基本数据类型,如本题出现了int i12=127,那么直接就是比较对应的值是否相等。。。。

注意一点就可以:Integer i=127表示的意思是自动装箱:底层调用Integer.valueOf(127)

如果值是在  -128到127之间返回的就是这个值。但是不在这个范围的时候,我们返回的就是通过这个值new出的Integer对象,自行查看valueOf源码。

解释一下示例五:一个是127,一个是new出来的对象,怎么可能返回true?肯定是false啊

String类(重点)

 

 这里的不可以修改的意思是:不可以修改指向的地址,但是指向的字符串的内容还是可以进行修改的

如图:value原来指向一个字符串,一旦被final修饰之后,不可以再指向其他地址的字符串,但是可以修改原先指向地址处字符串的内容

如图演示:被final修饰的value字符数组,不可以改变指向。只可以改变字符数组的内容。

不可以修改value的地址。但是可以修改 value数组的内容。

两种创建String对象的区别:

对于方式一:我们是直接用引用s(如图)指向指向这个常量池中的字符串的

对于方式二:

我们在堆空间中进行维护了value属性,用这个属性是指向常量池中的字符串。这个引用s2(如图)指向这个value属性的

对于维护这个value属性,我们看源码:

JVM内存图:

 分析:

第一种方式:直接赋值 String s="hsp";

在栈空间先创建一个局部变量对象引用s 存放地址,之后再在字符串常量池上进行查询,如果常量池中原本就存在这个常量字符串,那么就直接指向这个字符串,并且保存这个地址。如果不存在,我们再自己进行创建并且保存地址,注意是栈空间上的引用s直接指向常量池

第二种方式:调用构造器 String s2=new String("hsp");

先在栈空间中,创建一个实例对象引用s2,之后再在堆空间进行new一个对象空间,维护一个属性为value。并且把这个堆空间中的对象地址存放到栈空间的对象引用s2中。那么即是让s2指向堆空间中维护的value属性。之后发现参数为一个字符串,因此我们再从字符串常量池中进行寻找,如果存在,直接指向,并且把这个地址给到堆空间中维护的value属性进行存放。如果不存在,我们再自己进行创建一个常量字符串存到常量池中,并且把这个常量字符串的地址返回给堆空间维护的

value属性进行存放。这样形成了s2指向堆空间的value属性,value属性指向常量池中字符串。

String练习题

 对于==:我们知道既可以比较基本数据类型,也可以比较引用数据类型。我们知道String是引用数据类型,因此我们比较的是地址,两个对象new两次创建出的地址肯定不一样,所以第二个为false

对于equals:我们知道,它只可以比较引用数据类型,并且重写了String这个引用类型的equals方法,这里省略解释,肯定是true。【如果忘记可以查看深入学习Java-03中的解释】

intern方法:

对于intern这个方法,我们记住一点就行:无论如何,我们最终返回的就是字符串常量池中常量字符串的地址

 

 解释:

equals只可以比较引用数据类型,并且已经重写了String类型的equals方法,

1.为true

== 既可比较引用类型也可以比较基本数据类型,比较引用类型时,比较的就是地址。

我们通过作图可知:

a中存放的地址:是直接指向字符串常量池中常量字符串

b中存放的地址:在堆空间中对象的地址

因此 a==b

2.返回false

对于intern这个方法,我们记住一点就行:无论如何,我们最终返回的就是字符串常量池中常量字符串的地址

上面我们分析过 a和b存放的地址,所以

a==b.intern()

3.返回true

4.返回false

1.False

2.True

3.True

4.False

 

1.T  equals只可以比较引用类型 并且equals方法被重写了,所以比较的实际上是两个字符串的内容,所以为true

2.T  这个同理3  只会创建一份,因此地址肯定是一样的

3.T 对于String这个引用类型,==比较的就是地址,那么我们知道一个相同的字符串常量在常量池中只会创建一份,因此肯定是返回true

4. F

字符串对象的特性(重点)

我们要明白常量字符串在常量池中的创建规则:如果发现创建的字符串中在常量池中存在,那么更改指向即可。倘若不存在,我们再进行创建这个字符串常量存放到常量池中。 

本题:先在字符串常量池中创建一个字符串常量对象“hello”

然后执行第二句,在常量池中寻找看是否存在 haha 这个字符串,发现不存在,那么再创建一个字符串存放到常量池中,并且改变s1的指向,指向haha。

经典面试题:

哈哈哈哈哈

答案是一个对象。因为编译器底层会进行优化,

 

对于这个String a="hello";创建a对象,在内存中分布图:类似下图:a在栈区,对象hello在常量池中

这个我们要debug一下:

追进去:

添加一点特别重要的事情就是:

我们这里String  c=a+b;不一定非要 a和b都是变量,只要a和b不全是字符串常量,那么在编译的过程中肯定要进行接下来的过程。

过程:

先创建一个StringBuilder对象,之后通过StringBuilder的append方法把a对应常量字符串追加一下,同理接着把b对应的常量字符串也追加到后面。之后再在堆空间上创建一个String类型的对象

 1.调用StringBuilder

2.追加hello

3. 追加abc

4.调用底层的toString方法,把 helloabc 返回给你

总结:

我们知道了debug的这个过程之后,我们就可以画出内存图。

值得我们注意的就是 String c=a+b;的艰难创建过程。。。但是最终还是调用底层的toString方法

我们知道这个toString方法还是new一个对象返回的,

所以是new一个对象在堆空间开辟空间的,地址返回给c,c是指向堆空间中new出来的String类型的对象。堆空间中的对象中存放着常量池中字符串的地址。。。。

我们要明白: 

拓展:

c最终指向的是堆空间的地址,然而d指向的字符串常量池的地址,肯定是false啊

  String e="hello"+"abc"; 编译器会有一个优化机制,直接返回常量池中的helloabc这个字符串的地址返回给 e 所以d==e 返回true

 我们对于s1+s2 是经历了许多次debug可以知道,

但是对于intern方法明确一点就行,他一定是返回字符串常量池中字符串的地址的。

难题:

结果是:

分析:

从main方法中开始分析,一开始new出来一个Test1类型的对象存到堆空间中

重点是要分析出来:之后我们要在这个Test1new出来的对象空间中再进行new对象:String str=new String("hsp"); new出来一个String类型的对象。

同理,我们分配一个str作为对象实例引用指向,指向这个对象空间中存放的属性value,这个属性value指向字符串常量池中常量字符串:“hsp” 的地址。

同时一个重点就是:字符数组其实也是一个对象,是位于堆空间的。数组名作为一个地址相当于对象实例的引用,指向这个字符数组的内容。

下一步,我们调用方法change,根据前面的知识我们可以知道,每一次调用一个方法都会在栈空间开辟新的空间。

传过去的参数是 str的地址和ch这个字符数组的地址,,,

指向是一样的,

但是这个str和这个ch,这生成的线也是独立存在的和前面的线不一样。【毕竟是参数,都是存在于栈空间上的局部变量类型】

执行方法change:

str="java" :我们知道str指向的空间values,这个values空间指向的字符串常量池中没有 "java" 这个字符串。所以根据前面所学知识可知,我们会重新在常量池中写一个java,并且让str指向这个java

ch[0]='h'就是通过改变ch指向的数组内容

等该方法执行完之后,该方法在栈空间开辟的空间就会销毁。新开辟的str和ch这两个局部变量参数也会随之销毁,对应指向的线也随之消失。

但是之前在new Test1这个对象中 new出来的对象 new String("hsp") 是不会改变的。ch这个数组对象同样存在完好。

最后输出:hsphava

String类常用方法:

 

我们要注意第4个方法:

我们返回字符串对象中第一次出现的索引,注意是第一次

注意:

返回的是0,第一次出现we这个字符串的下标位置。。。。

5.获取该字符在字符串中最后一次出现的索引,如果找不到,返回-1。

 6.

name.substring(0,5)表示的意思是从下标为0处的字符截取到下标为5的字符的前一个即是 hello

我们也可以把0到5这个区间想象为一个左闭右开的区间即是从下标为0截取下标为4处 [0,5)==[0,4]

表示的意思是从下标为2开始截取到下标为5的前一个字符 即是llo

同上 想象为左闭右开的区间 [2,5)==[2,4]

 4.把字符串中的字符全部进行替换,如图:把林黛玉全部替换为薛宝钗

当然也可以直接写成s2,只要是字符串类型就可以

但是注意的是:

s1是没有发生任何的变化的,只是s1.replace()这个结果是变化的。我们前面能实现功能是因为,我们进行了  s1=s1.replace();这种s1的覆盖方式。。。。。。

看一下图中代码:s1是没有任何变化的,只是s1.replace()是不断的变化的

5.

当我们想要以 \\进行转义的时候,我们要使用转义字符:\ 。

分析一下 \\\\  :

第一个 \ 表示一个转义字符 它的意思是第二个\ 就是一个 \

第三个 \ 也表示是一个转义字符 它的意思是第四个 \ 就是一个 \  啊

 对于第7个方法,我们通过查看源码可知规则:

当我们从最短的字符串中可以比较出不同的时候,我们返回的就是前一个和后一个,第一个开始不同的字母的ASCII码的差值。

当我们不可以从最短字符串比较出来不同的时候,我们用的是第一个字符串的长度减去第二个字符串的长度。如图情况,结果为-1

结果为3

第二种情况就是,我们在比较完最短的字符串的时候,可以分辨出两个字符串有不同的字符 。

第三种情况就是,在把最短的字符串比较完之后,发现和较长的字符串前面都相同,那么只能用长度进行相减得结果。

8.

StringBuffer

 

注意第三点:

在数组中存放字符串的内容,数组存放在堆空间中,所以我们把字符串内容存放到堆空间中 。

然而对于String类型,我们每一次增加一个字符。不是说直接在字符串后面进行追加,

如果常量池中原来有,那么更换地址指向。

如果没有改变后字符串,那么在常量池中创建一个这个改变后的字符串,返回一个新的地址。

原来的字符串也不会删除,但是地址随着每一次的字符增加,每一次都要进行改变的。

 
 我们知道这个字符数组是存放于堆空间的,当我们增加内容的时候,不是说每一次都更新地址。当我们这一块数组的空间不够用的时候,我们才会进行开辟一个二倍(或者增加规定大小)的空间在堆空间中,并且把原来的字符串赋值到这个新开辟的空间。

这样就比较高效,不用说每增加一个字符就进行一次地址的更新。。。。

构造器的使用

指定大小

String类型转换为StringBuffer类型:

 

把StringBuffer转换为String:

StringBuffer方法(先掌握常用的六种方法)

删除,索引下标范围是左闭右开的

我们这里还依旧是左闭右开的范围区间,所以把赵敏替换为周芷若

重点:

 

StringBuffer练习

我们找源码:

1.

2.从append进去

 3.发现还是调用的是父类的append方法 ,那么再进去append

4.当str==null的时候,调用的是这个appendNull方法,再追进去

这个表示的空对象(null)转换成一个空字符的字符数组 {'n' 'u' 'l' 'l' }

分析:由上面的源码可知,当传入的字符串为null的时候,我们调用的是父类的appendNull方法

那么最后转换为一个字符数组之后,我们把这个数组进行返回(看看源码)

——接上面的图片

分析:

对于第一句:我们可以知道,sb返回回来的就是一个字符数组: {'n' 'u' 'l' 'l' },那么打印出来的就是null

对于第二句:我们就要看StringBuffer的构造器源码了:

 传进来的str是null,是空指针,所以null.length()会导致空指针异常。

一旦发生异常下面的代码就不会再执行

 StringBuilder

1.StringBuilder不是线程安全的,所以多线程的情况下是不建议使用的。但是在单线程的情况下,我们是建议使用StringBuilder的,因为StringBuilder在大多数情况下,它是要比StringBuffer速度要块的。

2.它俩拥有的方法差不多

2.串行化:对象可以进行网络传输,也可以保存到文件中。

第一条和第三条的源码依据:

第四条源码依据:

第五条源码依据:

如图:StringBuffer的方法是有互斥处理的,是适用于多线程的安全问题的。

但是StringBuilder则不一样,它是没有互斥处理的。

重点:String StringBuffer  StringBuilder的区别与选择场景

对于String:是不可变字符序列,效率低,但是复用率高。

如何解释一下复用率高呢?

我们在字符串常量池中,当我们修改字符内容的时候,不可以直接在后面追加字符。而是重新开辟一块新的空间去存放这个新的字符串内容,并且原来的字符串依然在常量池中保存一份。因此我们有了许多的字符串在常量池中保存。

举个例子:常量池中只有 leo这个字符串

但是我们想要leomessi这个字符串,我们不可以直接追加到eo后面一个messi

我们必须重新创建一个leomessi存到空间中

此时 空间中就包含了 leo和leomessi的字符串

假设说下一次我们再要找leomessi这个字符串,我们就可以复用上一次保存的leomessi

因为常量池中字符串,不断的改变过程中,改变前的字符串是不会改变的,依然是保存着的。

 

JavaSE学习笔记-08相关推荐

  1. JavaWeb黑马旅游网-学习笔记08【旅游线路详情】

    Java后端 学习路线 笔记汇总表[黑马程序员] JavaWeb黑马旅游网-学习笔记01[准备工作] JavaWeb黑马旅游网-学习笔记02[注册功能] JavaWeb黑马旅游网-学习笔记03[登陆和 ...

  2. 【计算机网络学习笔记08】ICMP

    [计算机网络学习笔记08]ICMP 1 概念 由[RFC 792]定义的因特网控制报文协议(Internet Control Message Protocol,ICMP),被主机和路由器用来彼此沟通的 ...

  3. ESP32 单片机学习笔记 - 08 - WebSocket客户端

    前言,终于要到网络模型的最后一层,第四层,应用层,http.websocket的实践了. 文章目录 ESP32 单片机学习笔记 - 08 - WebSocket客户端 一.应用层协议 科普概念 二.编 ...

  4. 【JavaSE学习笔记】

    JavaSE学习笔记 一.java的基本语法 变量运算规则 编码情况1中l后面没有加L,默认是int变量 编码情况2中b1=b+1中的1默认是int型变量,会出错 string类型 string里面可 ...

  5. JavaSE学习笔记(持续更新)

    这里写目录标题 JavaSE学习笔记(持续更新) Java跨平台原理与核心机制 1.跨平台原理: 2.两种核心机制: JDK11的安装流程 Java程序开发的三个步骤(无编辑器版) Eclipse安装 ...

  6. 重拾JavaSE学习笔记

    重拾JavaSE学习笔记 1.常用DOS命令 2.了解Java 2.1 .java特性 2.2.JDK .JRE.JVM 2.3.java的加载和执行 3.开发环境搭建 3.1.安装jdk 3.2.配 ...

  7. javaSE学习笔记01 入门篇

    javaSE学习笔记01 入门篇 java语言概述 Java背景知识 java是 美国 sun 公司 在1995年推出的一门计算机高级编程语言. java早期称为Oak(橡树),后期改名为Java. ...

  8. 我的javaSE学习笔记

    layout: post title: "我的JAVASE自学笔记" date: 2019-05-18 20:23:25 +0800 我的JAVASE自学笔记 作者:吴甜甜 个人博 ...

  9. JavaSE学习笔记-Day1

    笔者是一名大二在读本科生,最近闲着无聊重拾起Java这门语言,看了些许教学视频后居然还觉得挺有意思,"情不知所起,一往而深".于是决心认真学习这门语言!由于身居科班,自然不是零基础 ...

最新文章

  1. exchange迁移测试作业
  2. Flask入门之Jinjia模板的一些语法
  3. 移动端python开发_python前端之移动端库、框架及自动化和优化
  4. 在.NET开发中的单元测试工具之(1)——NUnit
  5. JQUERY项目所用插件
  6. 视频容器与编解码器的区别
  7. JVM 内存预警排查
  8. 递归系列——数组和对象的相关递归
  9. OTSU算法实现二值化
  10. 你们要的《Java工程师成神之路》高清版思维导图,来了!
  11. zabbix_proxy代理服务器搭建教程
  12. 蚂蚁链API参考接口
  13. [渝粤教育] 南通大学 模拟电子技术 参考 资料
  14. 想不想修真鸿蒙源液有什么用,想不想修真初代小世界怎么玩_想不想修真初代小世界玩法介绍_玩游戏网...
  15. ALSA子系统(一)------Frames Periods
  16. 【笔记】OpenSSL 使用
  17. 编译原理 —— 什么是编译
  18. 如何使用pandas分析金融数据
  19. java最简单最全入门基础笔记(不简单,不全你打我)
  20. 计算机报名为什么说我没有在系统用户中注册,硕士研究生网上报名常见问题汇总...

热门文章

  1. 一张图说明softmax layer是什么
  2. android涂鸦板保存功能,Android 使用Path实现涂鸦功能
  3. HDU - 1242
  4. 罗德里格旋转公式推导
  5. mysql几种性能测试的工具使用
  6. python 浏览器 弹 另存为_另存为弹出框如何调用
  7. 如何看待快码编程这一款中文多平台编程工具
  8. C++标准库(第二版,作者_NicolaiMJosuttis)_第六章标准模板库_6.2.4关联式数组
  9. 中国石油大学《物理化学》第三阶段在线作业
  10. 【单目标优化求解】基于matlab增强型黑猩猩优化器算法求解单目标优化问题【含Matlab源码 2013期】