前言
String类的源码中被final修饰——不可继承,同时不可被修改
一、创建对象?
-
直接赋值: String str = 值; 值存在Spring pool池中 创建一个对象,Spring pool 池中的匿名字符串对象
-
new 构造方法: String str = new String(值); 不推荐, 创建两个对象, 1.堆中的对象, 2.Spring pool 池中的匿名字符串对象
-
既然说new String 会创建两个对象,且说Spring的值不能改变那么:
String stu="Hello Spring";
stu=" Java";
String sut1=new Strin("Hello");
String stu2="Hello";
这里是不是stu所引用的String对象被修改了?
其实在jvm工作过程中,会创建一个内存空间专门存入String对象——.Spring pool 池;
String stu=“Hello Spring”;当jvm看到"Hello Spring",在String pool池创建String对象存储它,并将他的引用返回给stu。
stu=“Java”,当jvm看到"Java",在String池创建新的String对象存储它,再把新建的String对象的引用返回给stu。而原先的"Hello Spring"仍然在string池内。没有消失,他是不能被修改的。所以我们仅仅是改变了s的引用,而没有改变他所引用的对象,因为string对象的值是不能被修改的。
String stu1=“Hello”;jvm首先在String池内里面看找不找到字符串"Hello",找到,返回他的引用给stu1,否则,创建新的string对象,放到string池里。这里由于stu1=“Hello"了,对象已经被引用,所以依据规则stu和stu1都是引用同一个对象。所以 stustu1将返回true。(,对于非基本类型,是比较两引用是否引用内存中的同一个对象)
String stu2=String(“Hello”);jvm首先在string池内里面看找不找到字符串"Hello”,找到,不做任何事情,否则,创建新的string对象,放到string池里面。由于遇到了new,还会在内存上(不是string池里面)创建string对象存储"Hello",并将内存上的(不是string pool池内的)string对象返回给stu2。所以stu==stu2将返回false,不是引用同一个对象。
所以当使用new时大概就是现在String pool池里面找那对象,没找到则创建一个,当遇到new是则在内存空间(堆)友开辟一个对象空间。
二、字符串比较
- == 比较的是两个字符串对象是否是同一个对象, 地址码是否一样
- equlas() 比较的是两个字符串的内容是否相等, 实际开发中使用。
public static void main(String args[]) {
// 在池中和堆中分别创建String对象"abc",s1指向堆中对象
String s1 = new String("abc");
// s2直接指向池中对象"abc"
String s2 = "abc";
// 在堆中为"abc"创建新对象,s3指向该对象
String s3 = new String("abc");
// 在池中创建对象"ab" 和 "c",并且s4指向池中对象"abc"
String s4 = "ab" + "c"; // 结果: "abc" 两个字符串常量相加(拼接): 在编译期间: 已经做完拼接 s4="abc" 提高性能
// c指向池中对象"c"
String c = "c";
// 在堆中创建新的对象"abc",并且s5指向该对象
String s5 = "ab" + c; // 结果:"abc" 不会在编译期间进行拼接,因为 拼接是一个变量, 只能在运行时进行拼接
// 运行时拼接: 在堆创建一个空间(对象), 把拼接的结果赋值给堆对象,
System.out.println("------------实串-----------");
System.out.println(s1 == s2); //false
System.out.println(s1 == s3); //false
System.out.println(s2 == s3); //false
System.out.println(s2 == s4); //true
System.out.println(s2 == s5); //false
}
注意:
“内容”, 不仅仅是一个字符串的值, 还是一个String对象
“hello” 匿名String对象 直接调用String类的方法
任意东西与字符串相加, 结果都是字符串 任意数据类型转换为String, 1) 加"" 2) 调用toString()是Object
String转换为 int: Integer 的静态方法: int parseInt(String s)
String 转换为 double Double的静态方法: double parseDouble(String s)
String 转换为long Long的静态方法: long parseLong(String s)
三、字符串的常用方法
- 字符串比较的相关方法
1). equlas() 比较内容 , 区别大小写
2). equalsIgnoreCase(String anotherString) 比较内容是否相等, 不区分大小写
3). boolean contains(CharSequence s) 判断字符串是否包含某个内容 true 包含, false 不包含
4). boolean startsWith(String prefix) 判断字符串是否以某个开头 true: 是, false不是
5). boolean endsWith(String suffix) 判断字符串是否以某个结尾 true: 是, false不是
6). int compareTo(String anotherString) 比较两个字符串的大小 字典顺序( a-z) 安装字符的编码
0: 表示等于 > 0 表示大于 <0 表示小于
计算机: 底层: 使用二进制, gbk gb2312 big5 --> UTF-8 国际通用编码
String str=“12”;
String str2 = “100”;
比较大小: 先拿str第一位与str2的第一位比, 如果str的第一位大于str2的第一位, str > str2, 如果str的第一位小于str2的第一位, str < str2
如果str的第一位等于str2的第一位, 继续比第二位:
str > str2
- 字符与字符串
public String(char[] value)--------------------------全部字符数组变为String类
public String(char[] value,int offset,int count)-----部分字符数组变为String
public char charAt(int index)------------------------返回指定位置上的字符
int codePointAt(int 下标) ------------------------ 获取字符串指定下标的字符的ASCII编码
public char[] toCharArray()--------------------------字符串变为字符数组
- 字节数组与字符串
public String(byte[] bytes)--------------------------全部字节数组变为字符串
public String(byte[] bytes,int offset,int length)----部分字节数组变为字符串
public byte[] getBytes()-----------------------------字符串变为字节数组
`public byte[] getBytes(String charsetName)`throws UnsupportedEncodingException-----------------转码
- 字符串检索
public int indexOf(String str)-----------------------从头查找指定的子字符串是否存在,存在则返回字符串的索引,不存在则返回-1
public int indexOf(String str,int fromIndex)---------从指定位置开始检索,没找到则返回-1
public int lastIndexOf(String str)-------------------从后向前查找字符串的位置
public int lastIndexOf(String str,int fromIndex)-----从指定位置开始由后向前查找
- 字符串替换
public String replaceAll(String regex,String replacement)满足条件的内容全部替换
public String replaceFirst(String regex,String replacement)替换第一个满足条件的内容
- 字符串截取
public String substring(int beginindex)--------------从头截取到尾
public String substring(int beginindex,int endindex)-截取中间的部分内容
- 字符串拆分
public String[] split(String regex)------------------全拆分
public String[] split(String regex,int limit)--------拆分成指定的个数
- 其他方法
public boolean isEmpty()-----------------------------判断是否是空字符串,不是null
//判断是否是空字符串 "" boolean isEmpty() true 是空字符串, false 不是 //判断null 使用 == !=
public int length()----------------------------------取得字符串内容的长度
public String toLowerCase()--------------------------所有内容变为小写
public String toUpperCase()--------------------------所有内容变为大写
public String trim()--------------------------------去掉左右空格,中间的无法去掉
四、总结
今天就写了String类创建对象的内存空间与String pool池,知道为什么new是创建两个空间,同时列举了String的方法,其实查API也是很好的,我们要学会去查API,因为我们是不能把所有方法都记住的,看这些方法只是为了让自己有印象,知道去哪里找方法。