用好字符串,提防陷阱
来源:互联网 发布:ipad看电视剧软件 编辑:程序博客网 时间:2024/04/30 05:51
最基础的知识总是最容易忘记的,所以在回顾一下字符串吧,加深记忆
1、定义字符串的两种最常见的形式
String s1 = new String("字符串"); (1)
String s2 = "字符串"; (2)
那这两种有什么区别呢
实际上,由(1)种首先JVM会查看一下字符串池中有没有"字符串"这个直接量,没有的话,就在字符串池创建相应的直接量对应的字符串对象,然后再由new String()构造器返回的字符串对象,所以他实际上创建2个字符串对象
而第(2)种则只是检查字符串池中有没有"字符串"这个直接量,没有的话,就在字符串池创建相应的直接量对应的字符串对象
所以,可见,直接量创建的方式要比new方式创建效率高(其他封装类型也有相识的情况)
public class Test1{public static void main(String[] args){String s1 = "字符串";String s2 = "字符串";//输出trueSystem.out.println(s1 == s2);}}
2、字符串连接表达式可以在编译是确定下来,那么JVM会在编译是计算字符串变量的值,并让它指向字符串池中对应的字符串
public class Test2{public static void main(String[] args){String s1 = "字符串10";String s2 = "字" + "符串" + 10;//输出trueSystem.out.println(s1 == s2);}}
由于s1 、s2 在编译阶段已经指向了同一个直接量,所以运行时 == 为true
3、字符连接要是涉及到方法、变量(不是宏替换 final)时,编译时无语确定他的实际值
public class Test3{public static void main(String[] args){int len = 3;String s1 = "字符串的长度:3";String s2 = "字符串的长度"+"字符串".length();String s3 = "字符串的长度:" + len;//两个都输出falseSystem.out.println(s1 == s2);System.out.println(s1 == s3);}}
由于编译时,无法确定s2、s3变量的值,所以 == 为false;
然而,当变量为宏替换时,在编译阶段就已经替换为相应的值,也就是值已经确定
public class Test4{public static void main(String[] args){final int len = 3;String s1 = "字符串的长度:3";String s2 = "字符串的长度:" + len;//输出trueSystem.out.println(s1 == s2);}}
4、不可变长字符串
String s = "字符串" + "的长度" + "3";
看一下这段代码产生几个变量?
实际上,只有一个,因为JVM会在编译是就计算出s的值为“字符串的长度为3”,所以将该字符串存放在字符串池中,并让s指向它
那在看一下代码
public class Test5{public static void main(String[] args){String s = "字符串"; // 1System.out.println(System.identityHashCode(s));s = s + "的长度为:"; // 2System.out.println(System.identityHashCode(s));s = s + 3; //3 System.out.println(System.identityHashCode(s));}}
结果:
明明是同一个变量,为什么结果确实不相同的呢?
原来String字符串是不可变长的,也就是在第1句代码执行时,jvm将“字符串”直接量存入字符串迟,再将s指向它;在第2句执行时,jvm又生成“字符串的长度为”的直接量,再将s指向它,于是字符串池就有两个字符串变量了;第3句执行时字符串池就有三个变量了;
所以指向对象不同,hashcode肯定不同了,这种情况还要注意,因为在垃圾回收时,字符串池的变量不会被回收,很容易造成内存泄漏
所以,推荐使用StringBuffer、StringBuilder
两者的区别就是StringBuffer大部分方法是线程安全的,而效率也会低一点了
String由于不可变长,字符串改变时,指向变量改变,所以也是线程安全的了
public class Test6{public static void main(String[] args){StringBuilder s = new StringBuilder("字符串");System.out.println(System.identityHashCode(s));s.append("的长度");System.out.println(System.identityHashCode(s));s.append(3);System.out.println(System.identityHashCode(s));s.replace(0, 1, "23");System.out.println(s);System.out.println(System.identityHashCode(s));}}
结果:
总结:
1、String是不可变长的,同时他的new出来的对象会产生两个对象
2、在字符串连接比交多的地方,建议使用StringBuffer、StringBuilder
- 用好字符串,提防陷阱
- 提防浏览器兼容性视图设置陷阱
- 用好DELPHI中的字符串
- 用好Delphi中的字符串
- 用好Delphi中的字符串
- 用好Delphi中的字符串
- 第四部分 个人理财风险防范11.提防网络陷阱
- 国庆假期科技提示:提防“天价话费”陷阱
- 面试几点注意:需要提防的非语言陷阱
- 八类“求职陷阱”要提防 四类“陷阱合同”不能签
- 字符串输入的陷阱
- Java 字符串分割陷阱
- String字符串拼接陷阱
- C++字符串陷阱
- java 字符串,表达式,等陷阱
- 字符串输入的一些陷阱
- Java表达式的陷阱——关于字符串的陷阱
- C中字符串隐藏的陷阱
- 返回值为什么不能作为重载的一个条件
- python学习1:字典
- 用生产者消费者模型实现的线程安全环形队列
- python安装模块
- 分页SQL优化
- 用好字符串,提防陷阱
- 高斯卷积
- Java Read CSV File In Java With OpenCSV library, int filed 属性为 int类型
- 设置TCP阻塞模式下的发送和接收函数超时时间
- 第十一章 持有对象
- IOS近期更新暂停,可能会更新点关于产品,项目相关的东西
- Linux 常用函数——sprintf函数
- UIScrollView add button
- MFC中对话框控件的句柄和设备上下文的问题