String类解析
String
String结构
String对象是用来存储字符串,也是一组字符序列。
字符串常量对象是由双引号括起来的字符序列,如"你好","hello"等
字符串的字符采用Unicode编码,一个字符占两个字节
常用的构造方法:
String s1 = new String();
String s2 = new String(String original);
String s3 = new String(char[] a);
String s4 = new String(char[] a, int startIndex, int count);
String继承图
实现了Serializable接口,说明可以串行化,进行网络传输文件保存
实现了Comparable接口,说明String对象可以比较
String也是一个final类,说明不可以被继承
String有一个属性value,是这么定义的:private final char value[];
-
源码注释是value的作用是用来存放字符串
-
这里的final说明value这个字符数组,不可修改(地址不可改),即value不能指向新的地址,但是单个字符内容是可以改变的。
String创建分析
方式一:直接赋值 String s1 = "pcq";
方式二:调用构造器 String s2 = new String("pcq");
- 方式一的创建是在常量池中看有没有"hello"数据空间,如果有,就指向,如果没有,就创建"pcq"再指向
- 方式二是在堆中创建一个String对象,然后这个String对象的value属性,指向池中的“pcq”数据空间,同样的有就直接指向,没有就创建再指向(指向池中的是value)。但s2最终指向的是堆中的空间。
内存分布图
请看下列代码
String s1 = "aaaa";
String s2 = new String("aaaa");
System.out.println(s1.equals(s2));
System.out.println(s1 == s2);
1和2是String对象的创建,存放的字符串都是"aaaa",明显第3行输出的是true,问题是第4行,== 在比较引用类型的时候,比的是地址是否相同,这里s1是指向常量池中的地址,而s2指向的是堆中的空间,所以第四行输出的结果是false
字符串特性
String a = "hello" + "abc";
这里编译器会做一个优化 “hello” + “abc” --> “helloabc"
所以只会在池中创建一个对象
String a = "hello";
String b = "abc";
String c = a + b;
1和2没有问题,在池中创建了"hello"和"abc"两个对象,第三行就没那么简单了,第三行的执行步骤:
- StringBuilder sb = new StringBuilder();
- 执行sb.append("hello");
- 执行sb.append("abc")
- 执行String c = sb.toString(),return的是一个new String(......)
最后c就是指向堆中的对象,然后c的value指向池中的"helloabc"
String常用方法
-
equals 区分大小写,判断内容是否相等
-
equalslgnoreCase 忽略大小写的判断内容是否相等
-
length 获取字符的个数,字符串的长度
-
indexOf 获取字符在字符串中第1次出现的索引,索引从0开始,如果找不到,返回-1
-
lastIndexOf 获取字符在字符串中最后1次出现的索引,索引从0开始,如找不到,返回-1
-
substring 截取指定范围的子串
-
trim 去前后空格
-
charAt 获取某索引处的字符,注意不能使用Str[index]这种方式.
-
toUpperCase 转换成大写
-
concat 拼接字符串
-
replace 替换字符串中的字符
-
split 分割字符串, 对于某些分割字符,我们需要 转义比如
-
compareTo 比较两个字符串的大小,如果前者大,则返回正数,后者大,则返回负数,如果相等,返回 0
-
format 格式字符
占位符有:%s 字符串 %c 字符 %d 整型 %.2f 浮点型