说到Java中最常用的类,那么一定是非String类莫属了。刚学Java写hello world就用到了。虽然看起来简单但是还是有很多的细节需要注意。正因为常用我们才需要更加关注它的细节,这样我们才能用好。

1、不可变性

学过一段时间Java后一定听过String的这个特性:不可变性。为啥不可变呢?先来点源码(jdk1.8)看看:

public final class Stringimplements java.io.Serializable, Comparable<String>, CharSequence {/** The value is used for character storage. */private final char value[];/** Cache the hash code for the string */private int hash; // Default to 0

看到这个源码我们首先要注意的有2点,这两点其实也说明了String不可变的原因:
1、String类是final类型的,也就是说String类无法被继承,final修饰的类其实他的方法也是final类型的,只不过没有显式的声明,也就是无法通过继承来覆写String的方法。
2、String中用于存储字符串的value值其实是char类型的数组,或者说它底层的数据结构其实是char数组;并且这个数组是私有的(private)同样被final修饰。这就说明这个值是对外不可见的,并且一旦初始化内存地址就不能改变了,注意这里只是说内存地址不可变,但是String类想要修改value这个数组内部的值是可以的,比如value是{‘1’,‘2’},那么完全可以修改value为{‘0’,‘2’},但是String类并没有提供这种方法,为的就是保持String不可变。其他的源码没有贴,其实String用来修改字符串的方法,其实都是返回了一个新的字符串,并不是修改value的值。

2、replace、replaceAll和replaceFirst

replace:替换字符串中所有的字符或字符串
replaceAll:和replace一样,但是支持正则表达式
replaceFirst:替换字符串中第一次出现的内容,支持正则表达式
Java中替换空字符串也需要注意一下:

//首尾空格替换
String str = " x xxx x  ";
System.out.println(str.trim());
// 所有空格替换
String str = " x xxx x  ";
System.out.println(str.replaceAll(" ",""));
// 所有空白字符替换
String str = " x x    xx x  ";
System.out.println(str.replaceAll("\\s*",""));

3、split函数

split使用的时候也要注意一下,split函数结尾空串会被舍弃。这里给出几行代码思考一下运行看看:

String o = "oooooooo";
System.out.println(Arrays.asList(o.split("o")));
String o1 = "qoooooooo";
System.out.println(Arrays.asList(o1.split("o")));
String o2 = "ooooqoooo";
System.out.println(Arrays.asList(o2.split("o")));
String o3 = "qooooooooq";
System.out.println(Arrays.asList(o3.split("o")));
//如果需要保留结尾空字符串可以设置split函数第二个参数为-1
String o1 = "qoooooooo";
System.out.println(Arrays.asList(o1.split("o", -1)));

这里还有一点需要关注的是split函数是根据正则去匹配的,这种方式在处理比较大并且复杂的字符串时有可能会因为贪婪匹配导致回溯,导致cpu过高。所以在使用split函数处理非常复杂的字符串时一定要多加小心,可以采用其他的方式来代替的就用其他方式代替。

3、使用String时的+=问题

在使用String时尽量避免再循环中使用+=的操作进行拼接字符串,而是使用StringBuilder或者StringBuffer中的append方法代替。
为什么呢?因为我们都知道String对象是不可变的,在循环中去使用+=去拼接字符串会产生大量的字符串对象,而这些字符串对象很可能是没有意义的(就是只会在你这个循环中用到,是一种中间的状态,创建大量的字符串无疑是一种极大的资源开销,好钢用在刀刃上),而StringBuilder和StringBuffer中的append方法来拼接字符串的话就不会有这种问题,归根结底是因为在这两个类底层中是通过修改char[]的方式来达到修改字符串目的的,最后再将修改好的char数组转换成字符串,这样的好处就是我只是对char数组这一个对象动了手脚,并不会创建那么多中间状态的对象从而节省了系统资源开销,提升了运行速率。stringbuilder和stringbuffer的区别就是stringbuilder不是线程安全的,而stringbuffer是线程安全的,使用场景不同而已。看源码stringbuffer中的append方法是加了synchronized关键字的。

4、String的intern()方法

intern()方法是String类中的本地(native)方法。看下jdk1.8源码(凑一下字数):

/*Returns a canonical representation for the string object.
A pool of strings, initially empty, is maintained privately by the class String.
When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.
当调用intern方法时,如果字符串常量池中已经包含一个用equals方法判定相等的字符串(简单说就是你要创建的字符串常量池中已存在),那么就返回常量池中的字符串;否则就把这个字符串加入常量池,并返回这个字符串对象的引用。
It follows that for any two strings s and t, s.intern() == t.intern() is true if and only if s.equals(t) is true.
All literal strings and string-valued constant expressions are interned. String literals are defined in section 3.10.5 of the The Java™ Language Specification.
Returns:
a string that has the same contents as this string, but is guaranteed to be from a pool of unique strings.*/
@NotNull
public native String intern();

其实jdk中的注释已经很好的解释了intern方法的使用方法,关键的部分我也做了翻译(4级水平),只是这里涉及到了一个知识点就是字符串常量池:

因为我们已经知道String对象的不可变性,这也是Java中构建字符串常量池的基础,因为常量就是不可变的量,Java中引入字符串常量池主要目的就是节省创建对象和内存的系统开销用以节约资源(不需要为相同的字符串开辟更多的内存空间,举个栗子:就是你饿了想吃面包,有俩选择一个就是去超市直接买做好的,一个就是去面包店要求现烤。这时候常量池就像是超市),如果同一个字符串对象一会儿变成面包,一会儿又变成了矿泉水,那么这个常量池将变得没有意义。

其实字符串常量池我们几乎每天都在使用,只是可能你不会意识到而已,举个最简单不过的栗子:

String str = "123";

就上面这个不起眼的代码其实就已经在使用字符串常量池了,Java对String = xxx这个操作做了优化,就拿上面的这个栗子来说,我写了上述代码,要把123这个字符串赋值给str,1、Java会先创建一个名为str的引用,2、然后从字符串常量池中查找如果已经存在123,那么直接把内存地址返回给str;3、如果没找到,那就在字符串常量池中创建123这个对象,然后再把内存地址返回给str。看着是不是和intern方法很像?其实这就是String str = new String("123").intern();的简化写法。

还有一点需要注意的是jdk1.7及之前字符串常量池是在方法区(永久代)的,jdk1.8取消了方法区用元空间代替了,这时候字符串常量池就被放在了堆中并不是一起转移到元空间哦。

其实Java用常量池节省资源开销的做法不光体现在String中,其它地方也用到了常量池,比如Long会缓存-128-127这256个数字。这也启发了我们平时在开发中如果遇到类似的问题可以用这种方式来进行优化或者提供解决思路。

Java常用类:String相关推荐

  1. java常用类-----String类的源码分析、可变和不可变序列

    package cn.zxg.PackgeUse; /** * 测试StringBuilder,StringBuffer可变字符序列 */ public class TestStringBuilder ...

  2. java 字符串 面试题_Java常用类String的面试题汇总(java面试题)

    1.比较两个字符串时使用"=="还是equals()方法? 当然是equals方法."=="测试的是两个对象的引用是否相同,而equals()比较的是两个字符串 ...

  3. 返回值 包装类_(九)Java常用类

    (九)Java常用类 String类 概述 /*String:字符串,使用一对""来表示. * 1.String声明为final,不能被继承. * 2.String实现了Seria ...

  4. <十>java常用类(2)

    Java常用类-String类(二) String的常用方法1 一.方法概述 int length():返回字符串的长度 char charAt(int index):返回某索引处的字符 boolea ...

  5. Java笔记-常用类String

    常用类String 在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串. String 创建的字符串存储在公共池中. import java.util.Arrays; ...

  6. java常用类(Object、String、Math、Date)

    文章目录 java常用类(Object.String.Math.Date) 一.object类及其方法 1. getClass()方法 2. hashCode()方法 3. toString方法 4. ...

  7. 3.4 java基础总结①常用类String②Stringbuffer③Stringbuilder

    ①常用类String②正则表达式③Stringbuffer④Stringbuilder 一.String ①String内存分析 String str0 = "hello";预先放 ...

  8. 这些Java常用类,你必须要学会,还不快快收藏?(近两万字详细介绍)

    零基础学习之Java常用类 概述 包装类 和数学相关的类 String类 创建字符串对象 使用构造方法 使用静态方法 使用" " + 拼接 字符串对象的比较 字符串的常用方法 可变 ...

  9. java常用类的方法,java常用类的使用方法

    java常用类的使用方法 Interger:整数类型 1.属性. static int MAX_VALUE:返回最大的整型数: static int MIN_VALUE:返回最小的整型数: stati ...

  10. java 类 函数,java常用类和函数

    JAVA中常用类的常用方法_计算机软件及应用_IT/计算机_专业资料.. JAVA 中常用类的常用方法 一. java.lang.Object 类 1. clone ()方法 创建并返回此对象的... ...

最新文章

  1. 开始Windows Embedded Compact 7的第一个项目——虚拟机上的CEPC
  2. [Google Guava] 7-原生类型
  3. Filter若不写chain.doFilter(request,response)原Servlet路径代码不会被执行
  4. pycharm git gitee 如何将红色文件推送到repository?(将工作区内容添加到暂存区)(git add)
  5. [云炬创业基础笔记]第二章创业者测试12
  6. Linux共享库路径配置
  7. 玩客云刷windows做服务器_精选 | 搭建一个私人服务器如何?
  8. JMETER从JSON响应中提取数据
  9. 编码 括号_Java编码规范整理汇总
  10. 填充xarray数据集变量等于维度的形状
  11. CodeForces 164C Machine Programming 费用流
  12. 文本处理工具--正则表达式
  13. 现在被apihook搞郁闷了.....进展很慢...先放上几个必用的api说明吧.
  14. 关于SI4463和AIS的学习笔记
  15. 第三方对接秀米图文编辑器遇到的坑
  16. 小白新手web开发简单总结(三)-一个简单的Web开发项目
  17. 关于声音的前后左右上下的控制以及单声道立体声的区别
  18. 问题 D: 猫和兔子
  19. 电子元器件行业B2B交易系统:规范企业交易流程,提升销售管理效率
  20. 自用的一些平时记录. 时不时更新

热门文章

  1. 员工发布“宏颜获水”广告引争议 苏宁回应:系个人行为
  2. 这家公司把三星、联想、微软等7家公司给告了 侵犯其触摸屏专利
  3. 旗舰杀手!红米旗舰定名 干翻全场?
  4. 拳王虚拟项目公社:闲鱼知乎引流售卖虚拟资源的虚拟副业项目实操
  5. SQL COUNT() 语法总结及用法【原创】
  6. 什么是WEB?如何学习web
  7. AudioTrack 播放PCM音频数据
  8. python 线程中出现执行错乱_python线程中的同步问题
  9. Mysql5.7.2安装教程+下载地址(windows)
  10. 【Flink】Flink中流动的四种元素