java

位置:IT落伍者 >> java >> 浏览文章

不再纠结Java中的String类


发布日期:2022年12月27日
 
不再纠结Java中的String类
String是我们经常用到的一个类型其实有时候觉得写程序就是在反复的操作字符串这是C的特点在java中jdk很好的封装了关于字符串的操作今天主要讲的是三个类String StringBuffer StringBuilder 这三个类基本上满足了我们在不同情景下使用字符串的需求

先说第一个String

JDK的解释是 Strings are constant; their values cannot be changed after they are created也就是说String对象一旦被创建就是固定不变的了(你一定有问题但请先等一等耐心读下去)这样的一点好处就是可以多线程之间访问因为只读不写

一般情况下我们以下面两种方式创建一个String对象

两种方式是有区别的这和java的内存管理有关前面已经说过string创建之后是不可变的所以按照第一种方式创建的字符串会放在栈里更确切的是常量池中常量池就是用来保存在编译阶段确定好了大小的数据一般我们定义的int等基本数据类型就保存在这里

其具体的一个流程就是编译器首先检查常量池看看有没有一个string如果没有则创建如果有的话则则直接把str指向那个位置

第二种创建字符串的方法是通过new关键字还是java的内存分配java会将new的对象放在堆中这一部分对象是在运行时创建的对象所以我们每一次new的时候都会创建不同的对象即便是堆中已经有了一个一模一样的

写一个小例子

这个的运行结果是

true //解释两个字符串的内容完全相同因而指向常量池中的同一个区域

false //解释每一次new都会创建一个新的对象

false // 解释 注意==比较的是地址不仅仅是内容

true //介绍一下intern方法这个方法会返回一个字符串在常量池中的一个地址如果常量池中有与str内容相同的string则返回那个地址如果没有则在常量池中创建一个string后再返回实际上str现在指向了str的地址

这就是让人纠结的string了现在你可以说话了…很多人有这样的疑问就是既然string是不变的那么为什么str + some是合法的其实每次对string进行修改都会创建一个新的对象

所以如果需要对一个字符串不断的修改的话效率是非常的低的因为堆的好处是可以动态的增加空间劣势就是分配新的空间消耗是很大的比如我们看下面的测试

我的机器上运行结果是the run time is ms 如果你把循环的次数后面再增加几个就会更慢因为每一次循环都在创建心的对象那么JDK如何解决这个问题?

下面就要说第二个类StringBuffer

StringBuffer是一个线程安全的就是多线程访问的可靠保证最重要的是他是可变的也就是说我们要操作一个经常变化的字符串可以使用这个类基本的方法就是append(与string的concat方法对应)和insert方法至于怎么使用就不多讲了大家可以自己查看API

测试一下这次只需要ms这就是效率

那么接下来就要问StringBuilder是干什么的其实这个才是我们尝使用的这个就是在jdk 版本后面添加的新的类前面说StringBuffer是线程同步的那么很多情况下我们只是使用一个线程那个同步势必带来一个效率的问题StringBuilder就是StringBuffer的非线程同步的版本二者的方法差不多只是一个线程安全(适用于多线程)一个没有线程安全(适用于单线程)

其实看了一下jdk源代码就会发现StringBuffer就是在各个方法上加上了关键字syncronized

以上就是对三个字符串类的一个总结总之不要在这上面纠结……不想介绍太多的方法总觉得那样会把一篇博客弄成API文档一样而且还非常的繁琐都是些体会希望有所帮助起码不要再纠结尤其是面试…

上一篇:Spring容器对象(BeanFactory)

下一篇:struts2自定义验证器(身份证验证)