深入分析Java的String类的方法与特点

时间:2021-12-21 18:38:57

字符串是任何编程语言都必须支持的变量类型,有些编程语言是直接提供了原生的变量类型,有些编程语言则使用语法特性以 SDK 的形式提供支持。在Java编程平台中,对字符串的支持使用了后者的形式,就是通过在 JDK中提供一个名为String的类,对应字符串这个变量类型。

源码分析

既然JDK中的String类对应了字符串变量类型,为了熟练地掌握Java中字符串相关的技能,我们必须深入地分析和研究一下这个类。编码界有一句名言叫做 “源码面前,了无秘密”,因此,我们第一步就是来看看String类的源码概括。重点部分摘录如下:

public final class String implements 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
}

我们得出的几个重点是:

  1. String类的底层使用 char 的数组保存数据。
  2. String类是一个 final 类,不允许被继承。
  3. String类是一个 immutable 类,该类的对象生成后,内容不会发生变化。该类中的所有返回String类型对象的成员方法都是返回一个新的String对象

JVM内存模型

Java作为一门半编译半解释或者即编译又解释的编程语言,Java源码文件需要先被编译器编译成 ByteCode(字节码) 文件,然后在 JVM(Java虚拟机) 上解释执行。为了理解和掌握String类的特性,必须清楚地知道JVM的内存模型。对于字符串类型,也就是String类,JVM从编译源码到执行字节码的整个过程中,都做了特定的调整与优化,正是这些调整与优化造成了String类与对象的一些诡异特性。

关于JVM内存模型的分析与理解,可以参看我的另一篇文件或者通过其他的书籍与资料学习。与本文内容紧密相关的两个知识点总结如下:

  1. JVM的内存模型中有一块区域名为 方法区, 用于存储加载的类信息、方法体和各种符号表。
  2. 方法区中有一块区域名为 常量区, 用于存储编译时和运行时的字符串常量。

方法剖析

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与==

  1. 对于 ==,如果作用与基本数据类型(byte、short、char、int、long、float、double、boolean)的变量,则比较的是其存储的“值”是否相等;如果作用与引用类型的变量,则比较其所指向的对象的地址是否相同(即是否同一个对象)。在Java中,String是引用类型。
  2. 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”);

String strC = new String(“www.tiantianbianma.com”);
System.out.println(strA.equals(strB));
 System.out.println(strA == strB);
System.out.println(strA.equals(strC));
System.out.println(strA == strC);
System.out.println(strB.equal(strC));
System.out.println(strB == strC);

建议思考得出答案后,再上机验证结果。正确的答案是 true、false、true、false、true、false。他们在JVM中的内存布局简图如下:深入分析Java的String类的方法与特点

对照此图,答案就很清楚了。

编译优化

直接来看代码片段二:

final String str = “ma.com”;

String strA = “www.tiantianbianma.com”;
String strB = “wwww.tiantian” + “bianma.com”;
String strC = “www.tiantianbian” + str;
System.out.println(strA.equals(strB));
System.out.println(strA == strB);
System.out.println(strA.equals(strC));
System.out.println(strA == strC);

建议思考得出答案后,再上机验证结果。正确的答案是 true、true、true、true,希望没有出乎你的意料。背后的逻辑是Java编译器在编译源码时,对于编译时就可以确定的字符常量,包括字符序列和final字符变量,会自动进行拼接优化。

intern方法

String类中最诡异的一个方法就是 intern,还是先来看代码片段三:

String strA = “www.tiantianbianma.com”;
String strB = new String(“www.tiantianbianma.com”);
System.out.println(strA.intern().equals(strB.intern()));
System.out.println(strA.intern() == strB.intern());

建议思考得出答案后,再上机验证结果。正确的答案是 true、true。背后的原理是:无论是字符串常量区中的String对象,还是堆内存中的String对象,它们的intern方法都是去JVM中的字符串常量区获取相等字符序列的String对象返回。上述代码片段的JVM内存布局简图如下:

深入分析Java的String类的方法与特点

对照此图,答案就很清楚了。

总结

本文通过从源码入手,再到方法和特性的分析,基本上覆盖了Java中String类的重点和难点。特别是其中的不可变特性与编译优化特性,更是在实际项目中和笔试面试题中经常遇到,还有就是intern方法的诡异性。当然了,String的这些特性也不是完美的,不可变特性在大量拼接字符串时就会带来性能的极大损耗,所以需要使用StringBuilder 类或者 StringBuffer 类来代替。另外,本文对于String类中的方法的具体功能与注意点都没有仔细分析,但需要读者熟练掌握,无论对于笔试面试还是实际工作都大有裨益。

声明: 本文转载自IT技术分析网站: 天天编程,转载自 http://www.tiantianbianma.com/deep-insight-java-string-class/

深入分析Java的String类的方法与特点的更多相关文章

  1. Java中String类的方法及说明

    String : 字符串类型 一.      String sc_sub = new String(c,3,2);    //      String sb_copy = new String(sb) ...

  2. 【转载】Java中String类的方法及说明

    转载自:http://www.cnblogs.com/YSO1983/archive/2009/12/07/1618564.html String : 字符串类型 一.      String sc_ ...

  3. 『Java』String类使用方法

    Java中的字符串 java.lang.String类表示字符串类,Java程序中所有字符串文字都可以看作实现该类的实例. 特点: 字符串不可变:字符串的值在创建后不能在发生改变 public cla ...

  4. JAVA中String类的方法(函数)总结--JAVA基础

    1.concat()方法,当参数为两字符串时,可实现字符串的连接: package cn.nxl123.www; public class Test { public static void main ...

  5. java&period;lang&period;String 类的所有方法

    java.lang.String 类的所有方法 方法摘要 char charAt(int index) 返回指定索引处的 char 值. int codePointAt(int index) 返回指定 ...

  6. 《java入门第一季》之类(String类常见方法小叙)

    String类下面的构造方法和一些常见的方法: /* * 字符串:就是由多个字符组成的一串数据.也可以看成是一个字符数组. * 通过查看API,可以知道 * A:字符串字面值"abc&quo ...

  7. paip。java 高级特性 类默认方法&comma;匿名方法&plus;多方法连续调用&comma; 常量类型

    paip.java 高级特性 类默认方法,匿名方法+多方法连续调用, 常量类型 作者Attilax 艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http ...

  8. java中String类学习

    java中String类的相关操作如下: (1)初始化:例如,String s = “abc”; (2)length:返回字符串的长度. (3)charAT:字符操作,按照索引值获得字符串中的指定字符 ...

  9. java 中String类的常用方法总结,带你玩转String类。

    String类: String类在java.lang包中,java使用String类创建一个字符串变量,字符串变量属于对象.String类对象创建后不能修改,StringBuffer & St ...

随机推荐

  1. php对表格进行批量操作如全选反选删除功能

    <!DOCTYPE> <html> <head> <meta http-equiv="content-type" content=&quo ...

  2. Productivity Power Tools 动画演示&lpar;转&rpar;

    Productivity Power Tools 是微软官方推出的 Visual Studio 扩展,被用以提高开发人员生产率.它的出现一定程度上弥补和完善了 Visual Studio 自身的不足, ...

  3. jquery validate&period;addMethod 正则表达式 &lpar;自定义验证方法&rpar;

    项目中使用的jQuery添加的校验的方法 $(document).ready(function(){         5           6/* 设置默认属性 */         7$.vali ...

  4. AjaxPro2完整入门教程

    一.目录 简单类型数据传送(介绍缓存,访问Session等) 表类型数据传送 数组类型数据传送(包含自定义类型数据) 二.环境搭建 1.这里本人用的是VS2012. 2.新建一个空的Web项目(.NE ...

  5. NTP服务部署和测试

    1. 概述2. 部署3. 配置4. 客户端配置4.1 客户端安装ntpdate4.2 同步设置 1. 概述 本篇博客主要记录如何部署一台NTP服务器,用于内网时间同步. 时间服务器对于集群内部节点之间 ...

  6. 【实践】Matlab2016a的mdce集群搭建

    Matlab R2016a的mdce集群搭建 1.解压文件Matlab_R2016b_win64.iso. 文件下载地址:链接:https://pan.baidu.com/s/1mjJOaHa 密码: ...

  7. Java——Collections

    反转数组 Collections.reserve(ArrayList) 例子如下 /** * public class ListNode { * int val; * ListNode next = ...

  8. RN热更新

    说白了集成RN业务,就是集成RN离线包,解析并渲染.所以,RN热更新的根本原理就是更换js bundle文件和资源文件,并重新加载,新的内容就完美的展示出来了. 目前市场上出现的3种热更新模式如下:仅 ...

  9. 8 -- 深入使用Spring -- 8&period;&period;&period; Spring整合Hibernate

    8.8 Spring整合Hibernate 8.8.1 Spring提供的DAO支持 8.8.2 管理Hibernate的SessionFactory 8.8.3 实现DAO组件的基类 8.8.4 传 ...

  10. Centos 7配置docker-阿里云镜像加速

    阿里云加速网址:https://cr.console.aliyun.com/cn-hangzhou/mirrors(自行注册账密码) sudo mkdir -p /etc/docker sudo vi ...