JavaSE学习笔记-08
包装类 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相关推荐
- JavaWeb黑马旅游网-学习笔记08【旅游线路详情】
Java后端 学习路线 笔记汇总表[黑马程序员] JavaWeb黑马旅游网-学习笔记01[准备工作] JavaWeb黑马旅游网-学习笔记02[注册功能] JavaWeb黑马旅游网-学习笔记03[登陆和 ...
- 【计算机网络学习笔记08】ICMP
[计算机网络学习笔记08]ICMP 1 概念 由[RFC 792]定义的因特网控制报文协议(Internet Control Message Protocol,ICMP),被主机和路由器用来彼此沟通的 ...
- ESP32 单片机学习笔记 - 08 - WebSocket客户端
前言,终于要到网络模型的最后一层,第四层,应用层,http.websocket的实践了. 文章目录 ESP32 单片机学习笔记 - 08 - WebSocket客户端 一.应用层协议 科普概念 二.编 ...
- 【JavaSE学习笔记】
JavaSE学习笔记 一.java的基本语法 变量运算规则 编码情况1中l后面没有加L,默认是int变量 编码情况2中b1=b+1中的1默认是int型变量,会出错 string类型 string里面可 ...
- JavaSE学习笔记(持续更新)
这里写目录标题 JavaSE学习笔记(持续更新) Java跨平台原理与核心机制 1.跨平台原理: 2.两种核心机制: JDK11的安装流程 Java程序开发的三个步骤(无编辑器版) Eclipse安装 ...
- 重拾JavaSE学习笔记
重拾JavaSE学习笔记 1.常用DOS命令 2.了解Java 2.1 .java特性 2.2.JDK .JRE.JVM 2.3.java的加载和执行 3.开发环境搭建 3.1.安装jdk 3.2.配 ...
- javaSE学习笔记01 入门篇
javaSE学习笔记01 入门篇 java语言概述 Java背景知识 java是 美国 sun 公司 在1995年推出的一门计算机高级编程语言. java早期称为Oak(橡树),后期改名为Java. ...
- 我的javaSE学习笔记
layout: post title: "我的JAVASE自学笔记" date: 2019-05-18 20:23:25 +0800 我的JAVASE自学笔记 作者:吴甜甜 个人博 ...
- JavaSE学习笔记-Day1
笔者是一名大二在读本科生,最近闲着无聊重拾起Java这门语言,看了些许教学视频后居然还觉得挺有意思,"情不知所起,一往而深".于是决心认真学习这门语言!由于身居科班,自然不是零基础 ...
最新文章
- exchange迁移测试作业
- Flask入门之Jinjia模板的一些语法
- 移动端python开发_python前端之移动端库、框架及自动化和优化
- 在.NET开发中的单元测试工具之(1)——NUnit
- JQUERY项目所用插件
- 视频容器与编解码器的区别
- JVM 内存预警排查
- 递归系列——数组和对象的相关递归
- OTSU算法实现二值化
- 你们要的《Java工程师成神之路》高清版思维导图,来了!
- zabbix_proxy代理服务器搭建教程
- 蚂蚁链API参考接口
- [渝粤教育] 南通大学 模拟电子技术 参考 资料
- 想不想修真鸿蒙源液有什么用,想不想修真初代小世界怎么玩_想不想修真初代小世界玩法介绍_玩游戏网...
- ALSA子系统(一)------Frames Periods
- 【笔记】OpenSSL 使用
- 编译原理 —— 什么是编译
- 如何使用pandas分析金融数据
- java最简单最全入门基础笔记(不简单,不全你打我)
- 计算机报名为什么说我没有在系统用户中注册,硕士研究生网上报名常见问题汇总...
热门文章
- 一张图说明softmax layer是什么
- android涂鸦板保存功能,Android 使用Path实现涂鸦功能
- HDU - 1242
- 罗德里格旋转公式推导
- mysql几种性能测试的工具使用
- python 浏览器 弹 另存为_另存为弹出框如何调用
- 如何看待快码编程这一款中文多平台编程工具
- C++标准库(第二版,作者_NicolaiMJosuttis)_第六章标准模板库_6.2.4关联式数组
- 中国石油大学《物理化学》第三阶段在线作业
- 【单目标优化求解】基于matlab增强型黑猩猩优化器算法求解单目标优化问题【含Matlab源码 2013期】