目录
2.字符串常量,第一次出现,此时常量池中不存在,新建一个该对象加
一、JDK中String类的声明
为何String类被final修饰
被final修饰的类无法被继承,String类不存在子类。
这样的话就可以保证所有使用JDK的人,大家用到的String类仅此一个,大家都相同。什么时候会用到final修饰类你的这个类不希望有别的版本,到此为止。所有使用者用的这个类完全相同,没有别的实现。
二、创建字符串的四种方式。
方式一:直接赋值
String str = "hello world";
方式二︰通过构造方法产生对象
String str2 = new String("hello world");
方式三:通过字符数组产生对象
char[] data = new char[] {'a','b', 'c'};String str = new String(data);
方式四:通过String的静态方法valueOf(任意数据类型)=>转为字符串
String str = String.valueOf(10);
三、字面量:
1.字面量
10 -> int字面量
10.1 -> double字面量true -> boolean字面量
"abc" -> String字面量->就是一个字符串的对象。String str ="hello world";
String str = "hello world" ;
string str1 = str;
str1 = "Hello";
"Hello”也是字符串的字面量,是一个新的字符串对象,str1实际上指向了新的字符串对象"Hello"
⒉字符串比较相等
所有引用数据类型在比较是否相等时,使用equals方法比较,JDK常用类,都已经覆写了equals方法,大家直接使用即可。String,Integer。引用数据类型使用"=="比较的仍然是数值(地址是否相等)
string str1 == "hello";
String str2 == "hello" ;
system.out.println(str1 == str2);
//输出结果true
四、关于字符串的常量池问题
1.池的思想
所谓的"池"都是类似的思想
共享设计模式–节省空间(内存是一个非常紧俏的资源~~)字符串产生之后大部分情况都是用来进行输出处理,打印他的内容
数据库的连接池线程池都是类似的思想
2.字符串常量,第一次出现,此时常量池中不存在,新建一个该对象加
String str1 = new String("hello");
String str2 = new String("hello");
String str3 = new String("hello");
system.out.print1n(str1 == str2);
system.out.println(str2 == str3);
}
}
//输出 true
// true
并不是内容相同,只是说明str1和str2指向了相同的地址空间。
String str1 = new String("hello");
String str2 = new String("hello");
String str3 = new String("hello");
System.out.println(str1 == str2);
System.out.println(str2 == str3);
}
}
//false
//false
这三个引用指向了三个不同的字符串对象,所以false。
3.常量池
1.在我们使用直接赋值法来产生字符串对象的时候,JVM会维护一个字符串的常量池,这个常量池也是在堆中当这个对象在常量池中不存在的时候,那么会在常量池中直接产生这个对象
2.当使用直接赋值法产生字符串对象,发现该对象引用指向的内容在常量池中已经存在,那此时不会再产生新对象,而是直接复用常量池中已经有的对象
4.字符串的不可变性
所谓的字符串不可变指的是字符串对象的内容不能变,而不是字符串引用不能变。
string str = "hello";
str = str + "world";str += "!!! ";
system.out.println(str);
}
}
这里的不可变指的"hello" "world" "helloworld" "!!!"
"helloworld!!!"这些字符串对象一旦声明后就无法修改其内容。·
为何字符串的对象无法修改内容而其他类的对象能修改内容。
字符串其实就是一个字符数组-> char[],字符串保存的值实际上在数组中保存。
被final修饰
因此字符串对象的内容无法修改->String类的外部拿不到这个value数组
5.如何修改字符串的内容
a.在运行时通过反射破坏value数组的封装(了解,不推荐,ds部分讲反射大家就会写了,反射是所有框架的基础
b.更换使用StringBuilder或者StringBuffer类–已经不是一个类型了。使用方法和StringBuilder完全—样,线程安全,性能较差
c.若需要频繁进行字符串的拼接,使用StringBuilder类的append方法
StringBuilder sb = new StringBuilder();
sb.append("hello");
sb.append( "world");
sb.append("! ! !");
System.out.println(sb);
}
}
//输出he1lowor1d!!!
五、关于StringBuilder类的具体使用:
StringBuilder类和String类是两个独立的类,StringBuilder就是为了解决字符串拼接问题产生的。
因为String的对象无法修改内容,为了方便字符串的拼接操作,产生了StringBuilder类,StringBuilder类的对象是可以修改内容的。
String、StringBuilder、StringBuffer的区别:
1.String的对象无法修改,俩sb的对象内容可以修改。
2.StringBuffer是线程安全的操作,性能较差;StringBuilder是线程不安全,性能较高。
a.字符丰反转操作
stringBuilder sb = new StringBuilder( "hello");
sb.append( "123");
sb.reverse();
string str = sb.toString();
system.out.println(str);
}
}
//输出 321olleh
b.删除指定范围的数据
delete(int start,int end):删除从start索引开始end之前的所有内容。[start,end)
stringBuilder sb = new StringBuilder( "hello");
sb.append( "world");
sb.delete(5,10);
system.out.println(sb);
//输出 hello
c.插入操作
insert(int start,各种数据类型)
sb.delete(5,10);
sb.insert( offset: 4, i: 10);
system.out.println( sb);
}
}
//输出hell1o0
insert(4,10) =>10插入当前sb,插入之后10这个元素的索引就是4
重点总结
a.关于字符串常量池以及intern方法的理解问题
b.理解啥是个字符串不可变
c.StringBuilder的使用d.要使用String类,就采用直接赋值的方式。
e.要比较内容是否相等使用equals方法