iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >如何理解Java的String
  • 516
分享到

如何理解Java的String

2023-06-15 15:06:17 516人浏览 薄情痞子
摘要

本篇内容介绍了“如何理解Java的String”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1.String的特性1.1不变性我们常常听人说

本篇内容介绍了“如何理解Java的String”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

1.String的特性

1.1不变性

我们常常听人说,HashMap 的 key 建议使用不可变类,比如说 String  这种不可变类。这里说不可变指的是类值一旦被初始化,就不能再被改变了,如果被修改,将会是新的类,我们写个demo 来演示一下。

public class test {       public static void main(String[] args){         String str="hello";         str=str+"world";     } }

从代码上来看,s 的值好像被修改了,但从 debug 的日志来看,其实是 s 的内存地址已经被修了,也就说 s =“world”  这个看似简单的赋值,其实已经把 s 的引用指向了新的 String,debug  截图显示内存地址已经被修改,两张截图如下,我们可以看到标红的地址值已经修改了。

如何理解Java的String

如何理解Java的String

用示意图来表示堆内存,即见下图。

如何理解Java的String

我们可以看下str的地址已经改了,说了生成了两个字符串,String类的官方注释为Strings are constant; their values  cannot be changed after they are created. 简单翻译下为字符串是常量;它们的值在创建后不能更改。

下面为String的相关代码,如下代码,我们可以看到:

String 被 final 修饰,说明 String 类绝不可能被继承了,也就是说任何对 String  的操作方法,都不会被继承覆写,即可保证双亲委派机制,保证基类的安全性。

String 中保存数据的是一个 char 的数组 value。我们发现 value 也是被 final 修饰的,也就是说 value  一旦被赋值,内存地址是绝对无法修改的,而且 value 的权限是 private 的,外部绝对访问不到,String没有开放出可以对 value  进行赋值的方法,所以说 value 一旦产生,内存地址就根本无法被修改。

//char类型的final数组     private final char value[];              //hash值     private int hash;       private static final long serialVersionUID = -6849794470754667710L;

1.2相等判断

相等判断逻辑写的很清楚明了,如果有人问如何判断两者是否相等时,我们可以从两者的底层结构出发,这样可以迅速想到一种贴合实际的思路和方法,就像 String  底层的数据结构是 char 的数组一样,判断相等时,就挨个比较 char 数组中的字符是否相等即可。(这里先挖个坑,携程问过类似题目)

public boolean equals(Object anObject) {                      //如果地址相等,则直接返回true        if (this == anObject) {                    return true;         }               //如果为String字符串,则进行下面的逻辑判断         if (anObject instanceof String) {                     //将对象转化为String             String anotherString = (String)anObject;                   //获取当前值的长度             int n = value.length;                         //先比较长度是否相等,如果长度不相等,这两个肯定不相等             if (n == anotherString.value.length) {                                 char v1[] = value;                                char v2[] = anotherString.value;                int i = 0;                //while循环挨个比较每个char                     while (n-- != 0) {                                         if (v1[i] != v2[i])                                             return false;                         i++;                     }                             return true;             }         }                 return false;     }

相等逻辑的流程图如下,我们可以看到整个流程还是很清楚的。

如何理解Java的String

1.3替换操作

替换在平时工作中也经常使用,主要有 replace 替换所有字符、replaceAll 批量替换字符串、replaceFirst这三种场景。

下面写了一个 demo 演示一下三种场景:

public static void main(String[] args) {         String str = "hello Word !!";         System.out.println("替换之前 :" + str);         str = str.replace('l', 'd');         System.out.println("替换所有字符 :" + str);         str = str.replaceAll("d", "l");         System.out.println("替换全部 :" + str);         str = str.replaceFirst("l", "");         System.out.println("替换第一个 l :" + str);     }

输出的结果是:

如何理解Java的String

这边要注意一点是replace和replaceAll的区别,不是替换和替换所有的区别哦。

而是replaceAll支持正则表达式,因此会对参数进行解析(两个参数均是),如replaceAll("\\d",  "*"),而replace则不会,replace("\\d","*")就是替换"\\d"的字符串,而不会解析为正则。

1.4 intern方法

String.intern() 是一个 Native 方法,即是c和c++与底层交互的代码,它的作用(在jdk1.6和1.7操作不同)是:

如果运行时常量池中已经包含一个等于此 String 对象内容的字符串,则直接返回常量池中该字符串的引用;

如果没有, 那么在jdk1.6中,将此String对象添加到常量池中,然后返回这个String对象的引用(此时引用的串在常量池)。

在jdk1.7中,放入一个引用,指向堆中的String对象的地址,返回这个引用地址(此时引用的串在堆)。

public native String intern();

如果看上面看不懂,我们来看下一下具体的例子,并来分析下。

public static void main(String[] args) {         String s1 = new String("学习Java的小姐姐");         s1.intern();         String s2 = "学习Java的小姐姐";         System.out.println(s1 == s2);          String s3 = new String("学习Java的小姐姐") + new String("test");         s3.intern();         String s4 = "学习Java的小姐姐test";         System.out.println(s3 == s4);      }

我们来看下结果,实际的打印信息如下。

如何理解Java的String

为什么显示这样的结果,我们来看下。所以在 jdk7 的版本中,字符串常量池已经从方法区移到正常的堆 区域了。

  • 第一个false: 第一句代码String s1 = new String("学习Java的小姐姐");生成了2个对象。常量池中的“学习Java的小姐姐”  和堆中的字符串对象。s1.intern(); 这一句是 s1 对象去常量池中寻找后,发现 “学习Java的小姐姐” 已经在常量池里了。接下来String s2  = "学习Java的小姐姐"; 这句代码是生成一个 s2的引用指向常量池中的“学习Java的小姐姐”对象。结果就是 s 和 s2  的引用地址明显不同,所以打印结果是false。

  • 第二个true:先看 s3和s4字符串。String s3 = new String("学习Java的小姐姐") + new  String("test");,这句代码中现在生成了3个对象,是字符串常量池中的“学习Java的小姐姐” ,"test"和堆 中的  s3引用指向的对象。此时s3引用对象内容是”学习Java的小姐姐test”,但此时常量池中是没有  “学习Java的小姐姐test”对象的,接下来s3.intern();这一句代码,是将 s3中的“学习Java的小姐姐test”字符串放入 String  常量池中,因为此时常量池中不存在“学习Java的小姐姐test”字符串,常量池不需要再存储一份对象了,可以直接存储堆中的引用。这份引用指向 s3  引用的对象。也就是说引用地址是相同的。最后String s4 = "学习Java的小姐姐test";  这句代码中”学习Java的小姐姐test”是显示声明的,因此会直接去常量池中创建,创建的时候发现已经有这个对象了,此时也就是指向 s3 引用对象的一个引用。所以  s4 引用就指向和 s3 一样了。因此最后的比较 s3 == s4 是 true。

如何理解Java的String

我们再看下,如果把上面的两行代码调整下位置,打印结果是不是不同。

public static void main(String[] args) {         String s1 = new String("学习Java的小姐姐");         String s2 = "学习Java的小姐姐";         s1.intern();         System.out.println(s1 == s2);          String s3 = new String("学习Java的小姐姐") + new String("test");         String s4 = "学习Java的小姐姐test";         s3.intern();         System.out.println(s3 == s4);      }

如何理解Java的String

  • 第一个false: s1 和 s2 代码中,s1.intern();,这一句往后放也不会有什么影响了,因为对象池中在执行第一句代码String s =  new String("学习Java的小姐姐");的时候已经生成“学习Java的小姐姐”对象了。下边的s2声明都是直接从常量池中取地址引用的。s 和 s2  的引用地址是不会相等的。

  • 第二个false:与上面唯一的区别在于 s3.intern(); 的顺序是放在String s4 =  "学习Java的小姐姐test";后了。这样,首先执行String s4 = "学习Java的小姐姐test";声明 s4  的时候常量池中是不存在“学习Java的小姐姐test”对象的,执行完毕后,“学习Java的小姐姐test“对象是 s4  声明产生的新对象。然后再执行s3.intern();时,常量池中“学习Java的小姐姐test”对象已经存在了,因此 s3 和 s4 的引用是不同的。

2. String、StringBuilder和StringBuffer

2.1 继承结构

如何理解Java的String

2.2 主要区别

1)String是不可变字符序列,StringBuilder和StringBuffer是可变字符序列。

2)执行速度StringBuilder > StringBuffer > String。

3)StringBuilder是非线程安全的,StringBuffer是线程安全的。

“如何理解Java的String”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: 如何理解Java的String

本文链接: https://www.lsjlt.com/news/280695.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何理解Java的String
    本篇内容介绍了“如何理解Java的String”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1.String的特性1.1不变性我们常常听人说...
    99+
    2023-06-15
  • java String的深入理解
    java String的深入理解一、Java内存模型 按照官方的说法:Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。     JVM主要管理两种类型内存...
    99+
    2023-05-31
    java string ava
  • 如何理解JavaAPI中的String类
    如何理解JavaAPI中的String类,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。JavaAPI之String类[size=10.5000pt]一、所属包java.lang...
    99+
    2023-06-02
  • Java如何获取List<String>中的String详解
    目录前言问题场景问题讨论解决方案本文总结前言 在写这篇文章之前,我几乎没有思路去定义这个问题。只是知道,List<String>是泛型,是接口List<T>的...
    99+
    2024-04-02
  • 如何理解Java 虚拟机中的String 类和常量池
    本篇文章为大家展示了如何理解Java 虚拟机中的String 类和常量池,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。一、String 对象的两种创建方式String str1 ...
    99+
    2023-06-05
  • java中string报错如何解决
    在Java中,String报错可能是由于以下原因导致的:1. 未声明或未初始化String变量:确保在使用String变量之前,已经...
    99+
    2023-10-23
    java string
  • java的String类如何使用
    本文小编为大家详细介绍“java的String类如何使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“java的String类如何使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、认识String1.JDK...
    99+
    2023-06-30
  • 深入理解Java new String()方法
    问题一:这段代码创建了几个对象? String str1 = new String("aa"); 答案是两个 “aa”对象和String对象 其中有一项是常量池 常量池在Cla...
    99+
    2024-04-02
  • 如何理解Java注解
    本篇内容介绍了“如何理解Java注解”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!由@Autowired引...
    99+
    2024-04-02
  • 如何理解Java中的树
    这篇文章主要讲解了“如何理解Java中的树”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何理解Java中的树”吧!1 树的定义树实际上就是由许多个节点组成...
    99+
    2024-04-02
  • Java【String类】的详解
    目录 🐲 1.了解String类 🐲 2.String类常用方法 🦄 2.1 字符串构造 🦄 2.2 字符串查找 🦄 2.3 字符串截取 🦄 2...
    99+
    2023-08-31
    java
  • Java String类字符串的理解与认知
    目录一、前言二、String类概述三、字符串的特点四、String 构造方法图示:代码演示:五、String类对象的特点六、比较字符串的方法用法:代码图示:七、判断两个字符串地址是否...
    99+
    2024-04-02
  • Java中InputSteam如何转String
    小编给大家分享一下Java中InputSteam如何转String,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!InputSteam与String相互转化字符串被...
    99+
    2023-06-15
  • 如何解析String
    本篇文章给大家分享的是有关如何解析String,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。在java中,String类是一个很特别的类,首先它是一个final类,也就是imm...
    99+
    2023-06-03
  • 如何理解Java 中的RMI-IIOP
    本篇文章为大家展示了如何理解Java 中的RMI-IIOP,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。环境说明文中的测试代码放到了github上测试代码的JDK版本在文中会具体说明,有的代码会被重...
    99+
    2023-06-05
  • java String到底有多长?String超出长度该如何解决
    目录Java String 可以有多长?2种存在形式栈中的String堆中的StringString超出长度怎么解决?补充:Java string 长度不足补0的方法总结Java S...
    99+
    2023-01-30
    java中string有长度限制吗 Java中String string的长度
  • 如何理解Java中的逃逸
    这篇文章主要讲解了“如何理解Java中的逃逸”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何理解Java中的逃逸”吧! 在Java的编译体系中,一个Ja...
    99+
    2024-04-02
  • 如何理解JAVA的多线程
    这篇文章主要介绍“如何理解JAVA的多线程”,在日常操作中,相信很多人在如何理解JAVA的多线程问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何理解JAVA的多线程”的疑惑有所帮助!接下来,请跟着小编一起来...
    99+
    2023-06-02
  • Java的字节码如何理解
    Java的字节码如何理解,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。字节码是一套设计用来在Java 运行时系统下执行的高度优化的指令集,该Java 运行时系统称为Java 虚...
    99+
    2023-06-03
  • 如何理解对Java的异常
    这篇文章主要介绍“如何理解对Java的异常”,在日常操作中,相信很多人在如何理解对Java的异常问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何理解对Java的异常”的疑惑有所帮助!接下来,请跟着小编一起来...
    99+
    2023-06-15
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作