Java的包装类与String类详解(底层与内存)

封装类

封装类简介

定义

Java的数据类型分为基本数据类型和引用数据类型, 但是Java也为基本数据类型分别设计了对应的类
这就是包装类(Wrapper Classes)

8个包装类

其中除了Boolean和Character之外, 其他的六种包装类都继承自类Number

封装类性质

包装类初始化

手动拆箱装箱

  1. JDK5之前, Java采取的是手动拆箱和装箱方法
    手动装箱
public static void main(String[] args) {
        int n1 = 100;
        Integer integer = new Integer(n1);
        Integer integer1 = Integer.valueOf(n1);
        
    }

手动拆箱

int i = integer1.intValue();

自动拆箱装箱

  1. 但是JDK5之后, Java实现了自动装箱方法, 本质没有发生变化, 底层还是使用的valueOf()以及intValue()

自动装箱

int n2 = 100;
Integer integer2 = n2;

自动拆箱

int n3 = integer2;

包装类方法

1. 包装类转string

方式一

String str = integer1 + "";

方式二

String str2 = integer1.toString();

方式三

String str3 = String.valueOf(integer1);

2. String转包装类

方式一

String str = "12345";
Integer i1 = Integer.parseInt(str); // 自动装箱

方式二

Integer i1 = new Integer(str);

其他常用方法

  1. Integer的最大值和最小值, 其他包装类同理
Integer.MAX_VALUE
Integer.MIN_VALUE
  1. Character的isXXX() 方法, 可以判断是否是xxx

String

String剖析

结构剖析

  1. 使用Unicode编码, 一个字符(字母或者汉字)占用两个字节

  2. 实现Serializable接口, 可以串行化: 可以网络传输

  3. 实现了comparable接口 可以比较

  4. 实现了很多构造器

  5. String是final类, 不能被其他类继承

  6. String有属性 private final char value[], 用于存在字符串内容, 不可修改, 但是不代表字符不可修改
    代表的是地址无法修改

创建剖析

方式一: 直接赋值

String str = "AAA";

解释:
先从常量池查看有无"AAA", 如果有, 直接指向, 如果没有则重新创建, 然后指向
所以最终指向的是常量池的地址

方式二: 使用构造器

String str = new String("AAA");

解释
先在堆中创建空间, 里面维护了value属性, 指向常量池的"AAA"空间, 从常量池查看有无"AAA", 如果有, 直接令value指向, 如果没有则重新创建, 然后指向
所以最终指向的是堆中的地址

String对象特性

  1. 字符串是不可变的, 如果改变字符串, 其实会创建一个新的常量对象
String s1 = "AA";
s1 = "BB";

这里常量池会出现两个对象, 一个"AA", 一个"BB"

String str = "Hello" + "ABC";

这里不是创建三个对象, 只会创建一个对象, 因为编译器会优化, 等价于String str = "HelloABC"

String a = "AA";
String b = "BB";
String c = a + b;

前两句创建了两个常量池对象, 但是后面有所不一样

  1. 首先创建了StringBuilder对象
  2. 其次执行append方法, 将"AA" append进去
  3. 将"BB" append进去
  4. 返回的是StringBuilder的toString()方法

综上分析, 最后其实是让c指向堆中的对象, 然后这个对象的value数组指向常量池的"AABB"
所以a, b是常量池对象, c是堆对象

总结: 常量相加, 在常量池, 变量相加, 在堆

String常用方法

  1. equals() 区分大小写判断是否相等
  2. equalsIgnoreCase 不区分大小写判断是否相等
  3. length() 获取字符个数
  4. indexOf 获取字符在字符串中第一次出现的索引, (也可以传入字符串)
  5. lastIndexOf 获取字符在字符串中最后一次出现的索引
  6. substring 截取指定范围字符串
  7. trim 去前后空格
  8. charAt 获取某索引处的字符, 因为String不能利用[]索引
    ...
    PS: 有个印象, 到时候现查现用即可

StringBuffer

代表可变的字符序列, 可以对字符内容进行增删, 很多方法与String相同

结构剖析

  1. StringBuffer的直接父类是AbstractStringBuilder
  2. 实现了Serializable, 可以串行化
  3. 在父类中, 存在char[] value, 注意不是final, 所以存放在堆中
  4. StringBuffer是一个final类, 不可以被继承

结论: StringBuffer保存的是字符串变量, String保存的是字符串常量, 所以更改
StringBuffer的话可以直接更新内容, 不需要更改地址, 效率较高

StringBuffer转换与初始化

1.构造器

StringBuffer stringBuffer = new StringBuffer();

创建一个大小为16的char数组, 用来存放字符内容

StringBuffer stringBuffer = new StringBuffer(100);

可以直接指定char数组的容量

StringBuffer stringBuffer = new StringBuffer("hello");

当传入一个string时, 其实创建的char数组大小为string.length + 16, 然后再将string拼接进去

  1. String和StringBuffer之间的转化

String -> StringBuffer
1). 利用构造器(上述
2). 利用append 可以将String加到StringBuffer后面

StringBuffer -> String
1). 利用StringBUffer的toString方法
2). 使用构造器

String s = new String(stringBuffer);

StringBuffer方法

  1. append(str), 可以在buffer后面追加string, (传入int等也可以自动转成string)
  2. delete(l, r) 删除[l, r) 的字符
  3. replace(l, r, str) 使用str替换[l, r) 的字符
  4. indexOf(str) 查找指定字串在字符串中第一次出现的索引
  5. insert(x, str) 在索引为x的位置前面插入str
  6. length() 返回长度
    ...

StringBuilder

一个可变的字符序列, 提供了与StringBuffer兼容的API, 但是不保证同步(不是线程安全的)
该类呗设计用作StringBuffer的一个简易替换, 用在字符串缓冲区被单个线程使用的时候
如果可能, 建议优先采用该类, 因为在大多数实现中, 它比StringBuffer快

剖析

  1. 同样继承了AbstractStringBuilder
  2. 实现了Serializable, 可以串行化
  3. 同样是个final类, 不可以被继承
  4. 数据仍然存储在char[] value中, 所以仍然在堆中
  5. 不是线程安全的

StringBuffer, String, StringBuilder总结

  1. 如果字符串存在大量修改, 一般使用StringBuilder或者StringBuffer
    同时如果单线程, 使用String Builder, 否则使用StringBuffer

  2. 如果字符串很少修改, 被多个对象引用, 比如配置信息, 可以使用String

posted @   Xingon2356  阅读(30)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示