字符串是任何编程语言都必须支持的变量类型,有些编程语言是直接提供了原生的变量类型,有些编程语言则使用语法特性以 SDK 的形式提供支持。在Java编程平台中,对字符串的支持使用了后者的形式,就是通过在 JDK中提供一个名为String的类,对应字符串这个变量类型。
源码分析
既然JDK中的String类对应了字符串变量类型,为了熟练地掌握Java中字符串相关的技能,我们必须深入地分析和研究一下这个类。编码界有一句名言叫做 “源码面前,了无秘密”,因此,我们第一步就是来看看String类的源码概括。重点部分摘录如下:
我们得出的几个重点是:
- String类的底层使用 char 的数组保存数据。
- String类是一个 final 类,不允许被继承。
- String类是一个 immutable 类,该类的对象生成后,内容不会发生变化。该类中的所有返回String类型对象的成员方法都是返回一个新的String对象。
JVM内存模型
Java作为一门半编译半解释或者即编译又解释的编程语言,Java源码文件需要先被编译器编译成 ByteCode(字节码) 文件,然后在 JVM(Java虚拟机) 上解释执行。为了理解和掌握String类的特性,必须清楚地知道JVM的内存模型。对于字符串类型,也就是String类,JVM从编译源码到执行字节码的整个过程中,都做了特定的调整与优化,正是这些调整与优化造成了String类与对象的一些诡异特性。
关于JVM内存模型的分析与理解,可以参看我的另一篇文件或者通过其他的书籍与资料学习。与本文内容紧密相关的两个知识点总结如下:
- JVM的内存模型中有一块区域名为 方法区, 用于存储加载的类信息、方法体和各种符号表。
- 方法区中有一块区域名为 常量区, 用于存储编译时和运行时的字符串常量。
方法剖析
String类作为对应字符串的类,该类中含有大量的方法用来完成字符串相关的构造、裁剪、拼接与替换等功能。具体而言,在 JDK8 时,该类中已经有多于80个方法,好在其中有大部分都是重载方法。我们应该按照他们的功能把他们分类如下:
方法名 | 功能 | 方法名 | 功能 |
---|---|---|---|
String | 构造 | codePoint* | 取值 |
length | 长度 | getChars | 取值 |
isEmpty | 判空 | getBytes | 取值 |
charAt | 取值 | *equals* | 判等 |
compareTo* | 比较 | regionMatches | 正则 |
startWith | 判断 | *indexOf | 取值 |
substring | 截取 | concat | 拼接 |
replace* | 替换 | matches | 正则 |
contains | 包含 | split | 分割 |
join | 拼接 | to* | 转换 |
trim | 去空格 | format | 格式化 |
*valueOf | 转换 | intern | 获取 |
特性剖析
由于字符串类型的特殊性和频繁性,出于功能和效率的考虑,Java在处理字符串类型时,提供了几个重要的特性。
equals与==
- 对于 ==,如果作用与基本数据类型(byte、short、char、int、long、float、double、boolean)的变量,则比较的是其存储的“值”是否相等;如果作用与引用类型的变量,则比较其所指向的对象的地址是否相同(即是否同一个对象)。在Java中,String是引用类型。
- String的 equals 方法继承自Java中的超级父类Object,Object的equals方法用来比较两个对象的引用是否相等(即是否同一个对象)。但是,String的equals方法不仅是简单地继承,而是进行了重写(Override),用来比较两个String对象所存储的字符序列值是否相等。
创建方式
对于Java中的类而言,创建对象的方式一般有 5种。它们分别是 new 关键字、Class类的 newInstance 方法、Constructor类的 newInstance 方法、String对象的 clone方法、反序列化机制。但是String对象还有一种特殊的创建方式,就是通过使用 “ 或 ’ 包裹字符序列。现在,我们重点关注一下 new关键字 与 字符序列 这两种创建String对象的方式的异同。
我们直接以代码实例的方式来学习两种方式的优缺点。首先看代码片段一:
String strA = “www.tiantianbianma.com”;
String strB = new String(“www.tiantianbianma.com”);
建议思考得出答案后,再上机验证结果。正确的答案是 true、false、true、false、true、false。他们在JVM中的内存布局简图如下:
对照此图,答案就很清楚了。
编译优化
直接来看代码片段二:
final String str = “ma.com”;
建议思考得出答案后,再上机验证结果。正确的答案是 true、true、true、true,希望没有出乎你的意料。背后的逻辑是Java编译器在编译源码时,对于编译时就可以确定的字符常量,包括字符序列和final字符变量,会自动进行拼接优化。
intern方法
String类中最诡异的一个方法就是 intern,还是先来看代码片段三:
建议思考得出答案后,再上机验证结果。正确的答案是 true、true。背后的原理是:无论是字符串常量区中的String对象,还是堆内存中的String对象,它们的intern方法都是去JVM中的字符串常量区获取相等字符序列的String对象返回。上述代码片段的JVM内存布局简图如下:
对照此图,答案就很清楚了。
总结
本文通过从源码入手,再到方法和特性的分析,基本上覆盖了Java中String类的重点和难点。特别是其中的不可变特性与编译优化特性,更是在实际项目中和笔试面试题中经常遇到,还有就是intern方法的诡异性。当然了,String的这些特性也不是完美的,不可变特性在大量拼接字符串时就会带来性能的极大损耗,所以需要使用StringBuilder 类或者 StringBuffer 类来代替。另外,本文对于String类中的方法的具体功能与注意点都没有仔细分析,但需要读者熟练掌握,无论对于笔试面试还是实际工作都大有裨益。
声明: 本文转载自IT技术分析网站: 天天编程,转载自 http://www.tiantianbianma.com/deep-insight-java-string-class/
深入分析Java的String类的方法与特点的更多相关文章
-
Java中String类的方法及说明
String : 字符串类型 一. String sc_sub = new String(c,3,2); // String sb_copy = new String(sb) ...
-
【转载】Java中String类的方法及说明
转载自:http://www.cnblogs.com/YSO1983/archive/2009/12/07/1618564.html String : 字符串类型 一. String sc_ ...
-
『Java』String类使用方法
Java中的字符串 java.lang.String类表示字符串类,Java程序中所有字符串文字都可以看作实现该类的实例. 特点: 字符串不可变:字符串的值在创建后不能在发生改变 public cla ...
-
JAVA中String类的方法(函数)总结--JAVA基础
1.concat()方法,当参数为两字符串时,可实现字符串的连接: package cn.nxl123.www; public class Test { public static void main ...
-
java.lang.String 类的所有方法
java.lang.String 类的所有方法 方法摘要 char charAt(int index) 返回指定索引处的 char 值. int codePointAt(int index) 返回指定 ...
-
《java入门第一季》之类(String类常见方法小叙)
String类下面的构造方法和一些常见的方法: /* * 字符串:就是由多个字符组成的一串数据.也可以看成是一个字符数组. * 通过查看API,可以知道 * A:字符串字面值"abc&quo ...
-
paip。java 高级特性 类默认方法,匿名方法+多方法连续调用, 常量类型
paip.java 高级特性 类默认方法,匿名方法+多方法连续调用, 常量类型 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http ...
-
java中String类学习
java中String类的相关操作如下: (1)初始化:例如,String s = “abc”; (2)length:返回字符串的长度. (3)charAT:字符操作,按照索引值获得字符串中的指定字符 ...
-
java 中String类的常用方法总结,带你玩转String类。
String类: String类在java.lang包中,java使用String类创建一个字符串变量,字符串变量属于对象.String类对象创建后不能修改,StringBuffer & St ...
随机推荐
-
php对表格进行批量操作如全选反选删除功能
<!DOCTYPE> <html> <head> <meta http-equiv="content-type" content=&quo ...
-
Productivity Power Tools 动画演示(转)
Productivity Power Tools 是微软官方推出的 Visual Studio 扩展,被用以提高开发人员生产率.它的出现一定程度上弥补和完善了 Visual Studio 自身的不足, ...
-
jquery validate.addMethod 正则表达式 (自定义验证方法)
项目中使用的jQuery添加的校验的方法 $(document).ready(function(){ 5 6/* 设置默认属性 */ 7$.vali ...
-
AjaxPro2完整入门教程
一.目录 简单类型数据传送(介绍缓存,访问Session等) 表类型数据传送 数组类型数据传送(包含自定义类型数据) 二.环境搭建 1.这里本人用的是VS2012. 2.新建一个空的Web项目(.NE ...
-
NTP服务部署和测试
1. 概述2. 部署3. 配置4. 客户端配置4.1 客户端安装ntpdate4.2 同步设置 1. 概述 本篇博客主要记录如何部署一台NTP服务器,用于内网时间同步. 时间服务器对于集群内部节点之间 ...
-
【实践】Matlab2016a的mdce集群搭建
Matlab R2016a的mdce集群搭建 1.解压文件Matlab_R2016b_win64.iso. 文件下载地址:链接:https://pan.baidu.com/s/1mjJOaHa 密码: ...
-
Java——Collections
反转数组 Collections.reserve(ArrayList) 例子如下 /** * public class ListNode { * int val; * ListNode next = ...
-
RN热更新
说白了集成RN业务,就是集成RN离线包,解析并渲染.所以,RN热更新的根本原理就是更换js bundle文件和资源文件,并重新加载,新的内容就完美的展示出来了. 目前市场上出现的3种热更新模式如下:仅 ...
-
8 -- 深入使用Spring -- 8... Spring整合Hibernate
8.8 Spring整合Hibernate 8.8.1 Spring提供的DAO支持 8.8.2 管理Hibernate的SessionFactory 8.8.3 实现DAO组件的基类 8.8.4 传 ...
-
Centos 7配置docker-阿里云镜像加速
阿里云加速网址:https://cr.console.aliyun.com/cn-hangzhou/mirrors(自行注册账密码) sudo mkdir -p /etc/docker sudo vi ...