装箱:将基本类型用它们对应的引用类型包装起来;原理:Integer.valueOf() 方法
拆箱:将包装类型转换为基本数据类型;原理:Integer.intValue() 方法
Java 为每个原始类型提供了包装类型:
原始类型: boolean,char,byte,short,int,long,float,double
包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double
Java 基本类型的包装类的大部分都实现了常量池技术。
Byte
,Short
,Integer
,Long
这 4 种包装类默认创建了数值 [-128,127] 的相应类型的缓存数据,Character
创建了数值在 [0,127] 范围的缓存数据,Boolean
直接返回 True
or False
。
如果整型字面量的值在-128到127之间,那么自动装箱时不会new新的Integer对象,而是直接引用常量池中的Integer对象,超过范围 a1==b1的结果是false
Integer a1 = 128;
Integer b1 = 128;
System.out.println(a1 == b1); // false
Integer a2 = 127;
Integer b2 = 127;
System.out.println(a2 == b2); // true
不是。Java 中的基本数据类型只有 8 个,除了基本类型,剩下的都是引用类型基本数据
类型中用来描述文本数据的是 char,但是它只能表示单个字符,如果要描述一段文本,就需要使用 char 类型数组,但是使用数组过于麻烦,所以就有了 String,String 底层就是一个 char 类型的数组,只是使用的时候开发者不需要直接操作底层数组,使用更加简便
当JVM遇到上述代码时,会先检索常量池中是否存在“abc”,如果不存在“abc”这个字符串,则会先在常量池中创建这个字符串。然后再执行new操作,在堆内存中创建一个String对象,对象的引用赋值给s。此过程创建了2个对象。
当然,如果检索常量池时发现已经存在了对应的字符串,那么只会在堆内创建一个新的String对象,此过程只创建了1个对象。
final修饰的String类,代表了String类的不可被继承,final修饰的char[]代表了被存储的数据不可更改被创建,是无法修改的,即便你在后面拼接一些其他字符,也会把新生成的字符串存到另外一个地址但是,虽然final代表了不可变,但仅仅是引用地址不可变,并不代表了数组本身不会变。
因为字符串是不可变的,所以当创建字符串时,它的 hashcode 被缓存下来,不需要再次计算,所以相比于其他对象更快。
不一样,因为内存的分配方式不一样。String str="i"的方式,java 虚拟机会将其分配到常量池中;而 String str=new String(“i”) 则会被分到堆内存中。
indexOf():返回指定字符的索引。
charAt():返回指定索引处的字符。
replace():字符串替换。
trim():去除字符串两端空白。
split():分割字符串,返回一个分割后的字符串数组。
getBytes():返回字符串的 byte 类型数组。
length():返回字符串长度。
toLowerCase():将字符串转成小写字母。
toUpperCase():将字符串转成大写字符。
substring():截取字符串。
equals():字符串比较。
String类中使用字符数组保存字符串,private final char value[]
,所以string对象是不可变的。StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,char[] value
,这两种对象都是可变的。
String中的对象是不可变的,也就可以理解为常量,线程安全。
StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的
StringBuilder并没有对方法进行加同步锁,所以是非线程安全的
每次对String 类型进行改变的时候,都会生成一个新的String对象,然后将指针指向新的String 对象
StringBuffer每次都会对StringBuffer对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用StirngBuilder 相比使用StringBuffer 仅能获得10%~15% 左右的性能提升,但却要冒多线程不安全的风险。
StringBuilder > StringBuffer > String
总结:
1、在字符串内容不经常发生变化的业务场景,优先使用String类,例如常量声明、少量的字符串拼接操作等。
2、在单线程环境下,频繁地进行字符串的操作,建议使用StringBuilder,例如SQL语句拼装、JSON封装等
3、在多线程环境下,频繁地进行字符串的操作,建议使用StringBuffer,例如XML解析、HTTP参数解析与封装
形式 : 字符常量是单引号引起的一个字符,字符串常量是双引号引起的 0 个或若干个字符
含义 : 字符常量相当于一个整型值( ASCII 值),可以参加表达式运算; 字符串常量代表一个地址值(该字符串在内存中存放位置)
占内存大小 : 字符常量只占 2 个字节; 字符串常量占若干个字节 (注意: char
在 Java 中占两个字节
按功能来分:
输入流(input)、输出流(output)。
按类型来分:
字节流和字符流。
- 字节流
- Intputstream类:输入字节流的基类(抽象类)
- FileIntputStream类:字节输入流
- BufferedInputStream类:字节缓冲输入流(高效流)
- OutputStream类:输出字节流的基类(抽象类)
- FileOutputStream类:字节输出流
- BufferedOutputStream类:字节缓冲输出流(高效流)
- 字符流
- Reader类:输入字符流的基类
- FileReader类:读取字符文件的便捷流
- BufferedReader类:字符缓冲输入流(高效流)
- InputStreamReader类:字节流和字符流之间的桥梁(转换流)
- writer类:输出字符流的基类
- FileWriter类:写入字符文件的便捷流
- BufferedWriter类:字符缓冲输出流(高效流)
- OutputStreamWriter类:字节输出流和字符输出流之间的桥梁(转换流)
- 对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象
- 这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息
- 字节序列写到文件之后,相当于文件中持久保存了一个对象的信息
- 反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化
1、同步:调用者主动获取(等待或者轮询去查看结果)
2、异步:调用结果是被调用者在完成之后通知调用者
3、阻塞:该线程主动挂起
4、非阻塞:该线程不主动挂起而是继续执行
5、同步阻塞:调用者发出调用后,如果函数不能立即返回结果,则挂起所在的线程,等待结果(需要调用者主动去询问)
6、同步非阻塞:调用者在发出调用之后,如果当时有数据可读,则读取并返回,如果没有数据可读,则线程继续向下执行
7、异步阻塞:调用者发出调用之后,线程挂起,被调用的IO操作由系统来进行,等待结果之后,系统通过某种机制来通知调用者
8、异步非阻塞:调用者发出调用之后,线程基础进行其他操作,被调用的IO操作由系统来进行,有结果之后,系统通知调用者
一个IO操作分为俩个步骤:
发起IO请求
实际的IO操作
使用场景:
同步阻塞(BIO):线程发起IO请求,不管内核是否准备好IO操作,线程一直阻塞,直到完成
同步非阻塞(NIO):一个请求一个线程
异步非阻塞(AIO):一个有效请求一个线程
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_43296313/article/details/122940989
内容来源于网络,如有侵权,请联系作者删除!