说说String

C++:string类 1.字符串是表示字符序列的类2.标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作单字节字符字符串的设计特性。3. string类是使用char(即作为它的字符类型,使用它的默认和分配器类型关于模板的更多信 息,请参阅basic_string)。4. string类是模板类的一个实例,它使用char来实例化模板类,并用char_traits和allocator作为的默认参数根于更多的模板信息请参考。5. 阅读详情

String它是一个引用数据类型,不是一个基础数据类型。
先思考一个问题:String为什么是不可更改的。
查看String类的签名如下:

public final class String  
    implements java.io.Serializable, Comparable<String>, CharSequence {}  

然后再看看String到底是怎么存储字符串的:

/** The value is used for character storage. */  
    private final char value[];  

String类的签名,和存储String的char数组都被final修饰,它们确保了String对象是永远不会被修改的。

一、内存存储

下面我们继续String之旅吧,先贴一段学习代码。


public class LearnString {
    public static void main(String args[]) {
        String a = "abc";
        String b = "abc";
        String c = new String("abc");
        System.out.println(a == b);
        System.out.println(a == c);
        System.out.println(a.equals(c));
    }
}

运行结果也如大家所想:

true
false
true

我们先看看String的内存分布情况吧

public class LearnString {
     String b = "abc";
    public static void main(String args[]) {
        String a = "abc";
    }
}

编译后,我们通过javap -v LearnString来查看内存的分布情况,可以看到在字节码的Constant pool区有如下一行:

Constant pool:
   #1 = Methodref          #6.#23         // java/lang/Object."<init>":()V
   #2 = String             #24            // ab
   #3 = Fieldref           #5.#25         // com/example/learn/LearnString.d:Ljava/lang/String;
   #4 = String             #26            // abc

可见不管是成员变量还是局部变量,只要String一开始就被赋值了,那么它的值就会被保存在字节码的常量池中。其实你会发现如果把之前的:

String d = "ab" + "d";

重新编译后再javap后如下:

Constant pool:
   #1 = Methodref          #6.#23         // java/lang/Object."<init>":()V
   #2 = String             #24            // ab
   #3 = Fieldref           #5.#25         // com/example/learn/LearnString.d:Ljava/lang/String;
   #4 = String             #26            // abc

这时候我们可以发现结果是一样的,也就是说compiler发现这些”+”操作完全可以在编译阶段优化掉,compiler就会进行一定的优化操作。
接下来我们可以讨论开篇的那个例子了。“abc”字符串按照上面所说,在编译的时候就被保存在字节码的常量池中了,所以a 和 b都是拿的常量池中的“abc”值(指向了同一个堆地址),故a==b为true;c = new String(“abc”) ,它其实创建了两个对象,一个new出来的另一个就是常量“abc”,c的引用指向了new出来的对象,故a!=c。

    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof 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 (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

这是String重写Object的equals方法,由此可以发现equals方法是比较的是两个String对象里头的字符数组(char[]),比较的是堆中值而非堆地址,故a.equals(c)是相等。

二、注意的问题

先看看下面代码

String s = "";  
for(int i = 0; !"end".equals(args[i]);){  
      s+=args[i];  
}  

同样用javap反编译字节码

Classfile /F:/workspaces/JavaLearn/out/production/JavaLearn/com/example/learn/LearnString.class
  Last modified 2017-4-25; size 779 bytes
  MD5 checksum 646b7bf02cd674af0bc5e55605ee3713
  Compiled from "LearnString.java"
public class com.example.learn.LearnString
  minor version: 0
  major version: 50
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #10.#30        // java/lang/Object."<init>":()V
   #2 = String             #31            //
   #3 = String             #32            // end
   #4 = Methodref          #33.#34        // java/lang/String.equals:(Ljava/lang/Object;)Z
   #5 = Class              #35            // java/lang/StringBuilder
   #6 = Methodref          #5.#30         // java/lang/StringBuilder."<init>":()V
   #7 = Methodref          #5.#36         // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   #8 = Methodref          #5.#37         // java/lang/StringBuilder.toString:()Ljava/lang/String;
   #9 = Class              #38            // com/example/learn/LearnString
  #10 = Class              #39            // java/lang/Object
  #11 = Utf8               <init>
  #12 = Utf8               ()V
  #13 = Utf8               Code
  #14 = Utf8               LineNumberTable
  #15 = Utf8               LocalVariableTable
  #16 = Utf8               this
  #17 = Utf8               Lcom/example/learn/LearnString;
  #18 = Utf8               main
  #19 = Utf8               ([Ljava/lang/String;)V
  #20 = Utf8               i
  #21 = Utf8               I
  #22 = Utf8               args
  #23 = Utf8               [Ljava/lang/String;
  #24 = Utf8               s
  #25 = Utf8               Ljava/lang/String;
  #26 = Utf8               StackMapTable
  #27 = Class              #40            // java/lang/String
  #28 = Utf8               SourceFile
  #29 = Utf8               LearnString.java
  #30 = NameAndType        #11:#12        // "<init>":()V
  #31 = Utf8
  #32 = Utf8               end
  #33 = Class              #40            // java/lang/String
  #34 = NameAndType        #41:#42        // equals:(Ljava/lang/Object;)Z
  #35 = Utf8               java/lang/StringBuilder
  #36 = NameAndType        #43:#44        // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  #37 = NameAndType        #45:#46        // toString:()Ljava/lang/String;
  #38 = Utf8               com/example/learn/LearnString
  #39 = Utf8               java/lang/Object
  #40 = Utf8               java/lang/String
  #41 = Utf8               equals
  #42 = Utf8               (Ljava/lang/Object;)Z
  #43 = Utf8               append
  #44 = Utf8               (Ljava/lang/String;)Ljava/lang/StringBuilder;
  #45 = Utf8               toString
  #46 = Utf8               ()Ljava/lang/String;
{
  public com.example.learn.LearnString();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 6: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/example/learn/LearnString;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=3, locals=3, args_size=1
         0: ldc           #2                  // String
         2: astore_1
         3: iconst_0
         4: istore_2
         5: ldc           #3                  // String end
         7: aload_0
         8: iload_2
         9: aaload
        10: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
        13: ifne          40
        16: new           #5                  // class java/lang/StringBuilder
        19: dup
        20: invokespecial #6                  // Method java/lang/StringBuilder."<init>":()V
        23: aload_1
        24: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        27: aload_0
        28: iload_2
        29: aaload
        30: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        33: invokevirtual #8                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        36: astore_1
        37: goto          5
        40: return
      LineNumberTable:
        line 8: 0
        line 9: 3
        line 10: 16
        line 12: 40
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            5      35     2     i   I
            0      41     0  args   [Ljava/lang/String;
            3      38     1     s   Ljava/lang/String;
      StackMapTable: number_of_entries = 2
        frame_type = 253 /* append */
          offset_delta = 5
          locals = [ class java/lang/String, int ]
        frame_type = 250 /* chop */
          offset_delta = 34
}
SourceFile: "LearnString.java"

在执行”+”时候

        13: ifne          40
        16: new           #5                  // class java/lang/StringBuilder
        19: dup
        20: invokespecial #6                  // Method java/lang/StringBuilder."<init>":()V
        23: aload_1

在这个循环里每一次对String执行”+”操作,都会创建一个StringBuilder对象,可见这多么消耗性能。为了避免这种事情发生只要你在执行循环之前创建一个StringBuilder对象然后将之后的”+”操作换成StringBuilder.append()就可以。

【Window内核编程】——UNICODE_STRING,ANSI_STRING和PCHAR 【我的】Window驱动开发——UNICODE_STRING,ANSI_STRING和PCHAR 作者:zcr214 时间:2016/4/15   Windows驱动开发最常接触的就是指针了,各种类型的地址很容易搞晕,绝大多数的API需要的参数都是UNICODE_STRING的指针类型的,当我们自己要使用它的时候,多少会有些麻烦,需要借助ANSI_STRING和PCHAR才能转换到我们更熟悉 阅读详情

相关推荐

深入解析C#中的String和string

在C#语言中,String是.NET Framework类库中System.String类的别名,而string则是C#中的一个基础数据类型。两者在功能上是相同的,但是String是面向对象的引用类型,而string是C#的别名,它为String的简写。尽管使用时没有显著差异,但在一些特定的情况下,如泛型编程中,两者的区别可能会导致编译器的行为有所不同。字符串是编程中经常使用到的数据类型,在C#中也不例外。为了处理字符串数据,C#提供了丰富的字符串操作方法。

weixin_42400643的博客 1233

这一次我们来说说String和StringBuffer、StringBuilder的区别 !

又到了学习技术的时候了,千万不要懈怠,因为很多比你还优秀的人都还在努力学习呢!我之前听过非常有感触的一句话就是“以大多数人的努力程度之低,根本轮不到拼天赋”,说的非常有道理,你觉得呢? 今天我们一起来学习下 String和StringBuffer、StringBuilder的区别 ! 小白: 昨天没有发技术文章,发了一篇娱乐性的文章,效果怎么样呢? 庆哥: 这个,阅读量上去了,...

庆哥Java的优快云技术博客 2024

HT7036计量芯片SPI通信与数据读取实战解析

本文详细解析HT7036计量芯片的SPI通信与数据读取实战,涵盖SPI时序配置、命令发送、数据读取及常见问题排查。重点介绍如何通过SPI接口与MCU通信,实现电能数据的稳定采集与处理,为智能电表等应用提供实用解决方案。

vscode5coder的博客 267

说说string类

1. 为什么会有string类处理char型数组,封装标准C中一些字符串处理函数。容器2. 规格:有106个成员接口函数。有如此之多的原因:提高效率。(设计比较冗余,为了追求效率,省去了调用构造/析构函数及分配/释放内存的时间)用于实现常用操作3.实现:C++标准没有过多干预,不同厂商有不同实现。4.缺陷不支持多进/线程;模板技术水平没跟上;接口函数设计比较冗余,同一个功能上...

weixin_34319640的博客 142

电流镜结构实战:从零理解MOS管偏置电路设计(附吴金课程补充)

本文深入解析电流镜结构在MOS管偏置电路设计中的关键作用,从基本原理到实战应用全面覆盖。通过分析偏置电路的核心原理、破解设计难题的实用技巧,以及进阶优化策略,帮助工程师掌握这一模拟电路设计的核心技术。特别适合需要理解电流镜结构和基准电路设计的读者参考学习。

ujm5678901的博客 256

AF3​​​​​​​ Msa、TemplateHit、HitMetadata类解读

Msa:处理 多序列比对 (MSA) 结果,为 AlphaFold3 提供 序列进化信息。 TemplateHit:存储 查询序列与模板结构的比对信息,用于 筛选模板。 HitMetadata:提供 比对模板的 PDB 结构信息,帮助 解析和使用模板数据。

qq_27390023的博客 820

今天说说String相关知识点

String 如何实现以及特性 String类被final修饰,所以String不可被继承,Integer等等的包装类都不可以被继承。 jdk1.8中,String底层使用final修饰的char数组来存储字符串 private final char value[]; jdk1.9之后,底层使用final修饰的byte数组来存储字符串 private final byte[] value; 使用final关键字修饰,说明这个value数组初始化之后就不能引用其他数组,String内部也没有改变value

hsunnyc的博客 350

Jetson Orin Nano Super开发板实战:视觉模型部署与性能优化指南

本文详细介绍了Jetson Orin Nano Super开发板在边缘AI视觉模型部署与性能优化的完整实战指南。内容涵盖JetPack 6.1环境配置、Docker容器化部署、YOLO11及Transformer模型的TensorRT优化技巧,并通过实测数据展示了性能提升与功耗管理策略,为开发者提供高效的视觉AI部署解决方案。

7h6j5k4l3的博客 1196

【java学习记】String常用方法

String的常用方法

MLYClover的博客 251

Calibre :Standard Verification Rule Format(SVRF) Manual (1-2)

摘要:SVRF规则文件是用于Calibre和ICverify工具的脚本文件,包含层定义、规则检查、注释、预处理指令等元素。规则文件支持全局/局部层定义、隐式层操作,以及条件编译指令(#DEFINE/#IFDEF等)。宏功能(DMACRO/CMACRO)可实现代码复用,支持参数化层操作和嵌套调用。预处理指令支持版本控制(#IFDEFCALIBRE_VERSION)和环境变量默认值设置(#PRAGMAENV)。宏中的层名具有局部作用域,可通过特殊语法实现全局层名指定,LOCAL()修饰符可创建调用作用域内的唯一

u013620135的博客 1347

第4章 部署负载均衡 Keepalived + HAProxy

本章在所有 Master 节点部署 Keepalived + HAProxy,为 kube-apiserver 提供高可用入口。Keepalived 实现 VIP(192.168.3.59)漂移,HAProxy 轮询转发请求至三个 Master 的 6443 端口(监听 6444 避免冲突)。健康检查脚本连续 5 次失败则停止 Keepalived,触发 VIP 自动切换。本章还包含配置详解、日常运维和问题排查。

幸福街--linux技术分享 121

福州大学第十届程序设计竞赛+Problem A 神庙逃亡

Problem A 神庙逃亡 Accept: 214    Submit: 551 Time Limit: 1000 mSec    Memory Limit : 32768 KB Problem Description 话说最近穷猫猫LKity意外得到了一部ANDROID手机,于是,LKity兴奋地为自己的新机子安装了神往已久的游戏——神庙逃亡(Temple Run)。

wenlovingliu的专栏 1105

基于YOLOv10的PCB电子元件智能识别系统设计与实现

数据预处理模块:负责对原始PCB图像进行标注、增强和格式转换模型训练模块:基于YOLOv10架构进行模型训练和优化推理检测模块:加载训练好的模型进行实时检测用户界面模块:提供友好的交互界面,方便用户操作和结果可视化YOLO(You Only Look Once)系列算法自2016年提出以来,经历了多次迭代更新。YOLOv1-v3:奠定了YOLO系列的基础架构YOLOv4-v7:引入大量优化技巧和网络结构改进YOLOv8-v9:进一步优化模型结构和训练策略YOLOv10。

YOLO 157

Java String转String[]字符串数组,String[]转List集合,List集合转String,char[]字符数组转String

Java String转String[]字符串数组 String[]转集合 char[]字符数组转String 一、String转String[]字符串数组二、String[]转List集合 一、String转String[]字符串数组 方法:使用String的split()方法; split():根据匹配给定的正则表达式来拆分字符串,返回字符串数组(String[]); 注意:特殊字符的处理需要进行转义处理,如:"." 、""、"|"; 示例: String str = "1,2,3,4,5";

zhuzicc的博客 5379

【腾讯小龙虾WorkBuddy专栏05】深度解析WorkBuddy连接器(Connector)

深度解析WorkBuddy连接器(Connector)

AI人人懂 1318

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

String 和new String 的区别

String 和new String 的区别 JVM为了提升性能和减少内存开销,避免字符串的重复创建,维护了一块特殊的内存空间——字符串实例池。 1.String str = “xxx” String str = “test”; 以这种方式赋值时,JVM会先从字符串实例池中查询是否存在"test"这个对象,如果存在,直接把实例池中"test"的地址返回给str。如果不存在,则会在实例池中创建"te...

weixin_44844089的博客 3287

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

【C++】string

STL 库 string 详解

weixin_61091020的博客 1万+

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Java中String...和String[]的区别

首先,二者都有表示一个数组的意思。 1.String...只能用于方法的参数定义,不能用于初始化一个数组,如: public test(String... str) { //你的代码 } //调用时 test(new String[]{"aaa", "bbb"}); 而String[]则都可以使用,如: public test(String[] str) { //你的代码 } String[] str = new String[]{"hello", "world"};

weixin_41111189的博客 1万+

java String的经典问题(new String() ,String )

先来看一个例子,代码如下: 1.public class Test { 2. public static void main(String[] args) { 3. String str = "abc"; 4. String str1 = "abc"; 5. String str2 = new String("ab

niguang09的专栏 1万+

String、String Buffer、String Builder有啥子区别?

String、String Buffer、String Builder有啥子区别? jdk 1.8 String String类 是我们平时用的最多的一个类,它提供了构造和管理字符串的各种基本逻辑。 public final class String implements java.io.Serializable, Comparable<String>, CharSequ...

weixin_43519048的博客 2045

C++ String

C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列 的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户 自己管理,稍不留神可能还会越界访问。在OJ中,有关字符串的题目基本以string类的形式出现,而且在常规工作中,为了简单、方便、 快捷,基本都使用string类,很少有人去使用C库中的字符串操作函数。

Zengwengang的博客 411

String.Empty、string=”” 和null的区别

String.Empty是string类的一个静态常量; String.Empty和string=””区别不大,因为String.Empty的内部实现是: 1 2 3 4 5 6 7 8 9 10 11 12 publicstaticreadonlystringEmpt...

HD243608836的博客 4919

C#中String和string区别

String是一个类,string是一种数据类型. string是c#中的类,String是.net Framework的类(在c# IDE中不会显示蓝色) c# string映射为.net Framework的String 如果用string,编译器会把它编译成String,所以如果直接用String就可以让编译器少做一点点工作 如果使用c#,建议使用string,比较符合...

weixin_33962923的博客 1481

String

new String(bytes,encoding)    java中的String类是按照unicode进行编码的。    encoding所指的是bytes中的数据是按照encoding那种方式编码的,而不是最后产生的String是什么编码方式,最后产生是的unicode编码。    换句话说,是让系统把bytes中的数据由encoding编码方式转换成unicode编码。如果不指明,byt...

639

java中的string是什么意思_java中String[][] 是什么东西?string[]又是什么东西?

展开全部String[][]是二维数组。例如:String[][]str=newString[4][4],这是创建了一个有4行4列元32313133353236313431303231363533e78988e69d8331333366306433素的数组。String[]代表一维数组。例如:String[]str=newString[4],这个创建一个有4个元素的数组。String[]代...

weixin_33174889的博客 1万+

java string 最大长度_String的最大长度是多长

初看到这个问题心里还是有点尴尬的,平时确实没注意过String最大能有多长。想要知道String到底有多长,只能从源码层面来找答案了。Java中String不是基本数据类型,而是引用类型并且是final。String定义为final的原因:高效性JVM在查找字符串的时候可以直接定位到String类中,更准确的说String不可变,才能实现常量池。安全性定义成final,不能被继承和修改,可以防止在...

weixin_35854667的博客 4297
上一篇: Java的四种对象引用类型
下一篇: Java中的Collection
码农驿站
博客等级 码龄10年 5粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值