这里写目录标题
- 包装类(Wrapper)
- 包装类和基本数据的转换
- String VS StringBuffer VS StringBuilder
- String
- StringBuffer
- StringBuilder
包装类(Wrapper)
针对八种基本数据类型相应的引用类型
基本数据类型 | 包装类 |
---|---|
boolean | Boolean |
char | Character |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
Boolean、Character
包装类和基本数据的转换
-
装箱(Boxing)
装箱是将基本数据类型转为对应的包装类对象的过程,可以直接通过赋值或者方法调用
int primitiveInt = 42; Integer wrapperInt = primitiveInt; // 自动装箱 底层使用的是Integer.valueOf(primitiveInt) 或者显示装箱 int primitiveInt = 42; Integer wrapperInt = Integer.valueOf(primitiveInt); // 手动装箱 字符串转为包装类 String str = "123"; Integer wrapperInt = Integer.valueOf(str);
-
拆箱(Unboxing)
拆箱是将包装类对象转为基本数据类型的过程,它可以直接通过赋值或者方法调用完成
Integer wrapperInt = 42; int primitiveInt = wrapperInt; // 自动拆箱 或者显示的拆箱 Integer wrapperInt = 42; int primitiveInt = wrapperInt.intValue(); // 手动拆箱 包装类转为字符串 Integer wrapperInt = 123; String str = wrapperInt.toString();
Integer.valueOf(int)源码分析:
Integer.valueOf(int) 方法是用于将一个 int 值转换为对应的 Integer 对象的静态方法。
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i); //超过范围后,才会重新new一个对象
}
- 首先检查给定的证书是否在 [ − 128 , 127 ] [-128,127] [−128,127]范围之内;
- 如果在这个范围之内,就会从缓存中获取Integer对象,而不是创建一个对象,这样可以减少对象的创建和内存消耗;
- 如果不在这个范围之内,就会创建一个新的Integer对象,存储到堆。
例如:
Integer num1 = Integer.valueOf(1);
Integer num2 = Integer.valueOf(1);
System.out.println(num1==num2); //true,都指向同一个对象
Integer num1 = Integer.valueOf(128);
Integer num2 = Integer.valueOf(128);
System.out.println(num1==num2); //false,由于超过除了缓存范围,创建一个新Integer对象
String VS StringBuffer VS StringBuilder
类型 | 说明 | 效率 | 优点 | 使用场景 |
---|---|---|---|---|
String | 不可变的字符序列 | 低 | 复用率高 | 字符串很少修改 |
StringBuffer | 可变的字符序列 | 较高 | 线程安全 | 字符串存在大量修改,并在多线程 |
StringBuilder | 可变的字符序列 | 最高(单线程) | 线程不安全 | 字符串存在大量修改,并在单线程 |
String
String对象是用于保存字符串,也就是字符序列;
字符串常量对象使用双引号括起来的字符序列,例如:“你好”、“12.97”;
字符串的字符使用Unicode字符编码,一个字符占两个字节。
- Serializable:子类可以实现串行化,可以在网络传输;
- Comparable:子类可以比较;
常见的构造器:
String (String)
:直接通过字符串创建String (char[])
:使用字符数组创建字符串String (char[], int, int)
:使用字符数组的一部分来创建一个字符串对象。第二个参数是起始索引,第三个参数是子数组的长度。String (byte[])
:接受一个字节数组来创建一个字符串对象String (byte[], int ,int)
:使用字节数组的一部分来创建一个字符串对象。第二个参数是起始索引,第三个参数是子数组的长度。
特性:
String str1="hello"; //对象存放在常量池中
String str2=new String("hello") //对象存放在堆中
- String是final修饰的类,无法被其他类继承;
- 字符串是不可变的,一个字符串对象一旦被分配,其内容就无法修改
String s1="hello"
s2="hahah"
在方法区的常量池中,实际上创建了两个对象:hello、hahah
String a="hello"+"world"; 实际上只创建了一个对象:helloworld
String str1="hello";
String str2="world";
String str4=str1+str2;
- 当执行**
String str4 = str1 + str2
,Java编译器会使用StringBuilder
**类来处理字符串的拼接。 - StringBuilder s=new StringBuilder()对象,str1、str2的内容会复制到StringBuilder的缓存区中;
- sb.append(str1)、sb.append(str2);
- String str4=sb.toString();底层实际上是在堆中创建了一个对象;
最后在常量池中创建了三个对象:hello、world、helloworld。
StringBuffer
-
StringBuffer的直接父类是AbstractStringBuilder;
-
继承Serializable接口,对象可以串行化(网络传输);
-
在父类中,AbstractStringBuilder有属性char[] value,用于存储字符,不是final修饰;
-
StringBuffer是一个final类,无法被继承
StringBuffer VS String
- String保存的字符串常量,每次更新String类就是更改地址,效率低。
- StringBuffer保存的是字符串变量存放在char[]数组,内容可以更改,不用每次更新地址(创建新对象),效率高。
常见构造器:
new StringBuffer()
:无参数构造方法,创建一个空的 StringBuffer 对象,初始容量为 16 个字符。new StringBuffer(int capacity)
:带有容量参数的构造方法,创建一个具有指定容量的 StringBuffer 对象。如果预计字符串将比较长,可以指定一个较大的容量以避免频繁的扩容操作。new StringBuffer(String str)
:创建一个包含指定字符串内容的 StringBuffer 对象,初始容量为str.length() + 16
。
源码分析:
StringBuffer sb = new StringBuffer("hello");
-
初始化char[]数组的容量为
str.length() + 16
-
执行append方法,将字符串添加到char[]数组,可以看到StringBuffer是线程安全的。
-
最后完成数据存储
常见方法:
append(String str)
:将指定的字符串附加到当前字符串的末尾。insert(int offset, String str)
:在指定的偏移量位置插入指定的字符串。delete(int start, int end)
:删除从指定开始位置到结束位置之间的字符。deleteCharAt(int index)
:删除指定索引位置的字符。replace(int start, int end, String str)
:用指定的字符串替换从开始位置到结束位置之间的字符。substring(int start)
:返回从指定位置开始到字符串末尾的子字符串。。length()
:返回字符串的长度(字符数)。charAt(int index)
:返回指定索引位置的字符。
StringBuilder
一个可变的字符序列。
StringBuilder是线程不安全的,用在字符串缓冲区被单个线程使用的时候。
父类关系图:
- StringBuilder的直接父类是AbstractStringBuilder;
- 实现了Serializable接口,对象可以串行化(对象可以网络传输/保存到文件);
源码分析:
-
StringBuilder是final类,无法被继承;
-
字符序列存放AbstractStringBuilder的char[] value数组,因此存放在堆中。
-
StringBuilder所有的方法没有互斥处理(synchronized),因此推荐在单线程的情况下使用;
通过这种方式,您可以更清晰地呈现每个注解的信息和源码分析,使读者更容易理解和学习Java常用包装类的使用。希望这次的修改对您有所帮助!如果需要进一步的修改或补充,请随时提出。