Java之String

30分钟上手YOLO26 nano:INT8量化部署到智能相机,推理速度提升43% 微调代码(仅需5行,数据集遵循COCO格式)data="custom_data.yaml", # 数据集配置文件epochs=20, # 少量轮数即可收敛batch=8,imgsz=640model.save("yolov26n_custom.pt") # 保存微调后的模型本文在30分钟内完成了YOLO26 nano的INT8量化与智能相机部署,核心步骤为环境准备→模型获取→ONNX导出→INT8量化→部署推理。 阅读详情

Java之String

开篇

下面这段代码的输出:


        String str1= "abc";
        String str2= new String("abc");
        String str3= str2.intern();

        System.out.println(str1==str2);

        System.out.println(str2==str3);

        System.out.println(str1==str3);


String对象的内部实现

图示:

图1.png

  • 在 Java6 以及之前的版本中,String 对象是对 char 数组进行了封装实现的对象,主要有四个成员变量:char 数组、偏移量 offset、字符数量 count、哈希值 hash。

String 对象是通过 offset 和 count 两个属性来定位 char[] 数组,获取字符串。这么做可以高效、快速地共享数组对象,同时节省内存空间,但这种方式很有可能会导致内存泄漏。

  • 从 Java7 版本开始到 Java8 版本,Java 对 String 类做了一些改变。String 类中不再有 offset 和 count 两个变量了。这样的好处是 String 对象占用的内存稍微少了些,同时,String.substring 方法也不再共享 char[],从而解决了使用该方法可能导致的内存泄漏问题。

  • 从 Java9 版本开始,将 char[] 字段改为了 byte[] 字段,又维护了一个新的属性 coder,它是一个编码格式的标识。

为什么这样修改?

一个 char 字符占 16 位,2 个字节。这个情况下,**存储单字节编码内的字符(占一个字节的字符)就显得非常浪费。JDK1.9 的 String 类为了节约内存空间,**于是使用了占 8 位,1 个字节的 byte 数组来存放字符串。

而新属性 coder 的作用是,在计算字符串长度或者使用 indexOf()函数时,我们需要根据这个字段,判断如何计算字符串长度。coder 属性默认有 0 和 1 两个值,0 代表 Latin-1(单字节编码),1 代表 UTF-16。如果 String 判断字符串只包含了 Latin-1,则 coder 属性值为 0,反之则为 1。

String 对象的不可变性

String 类被 final 关键字修饰了,而且变量 char 数组也被 final 修饰了

类被 final 修饰代表该类不可继承,而 char[] 被 final+private 修饰,代表了 String 对象不可被更改。Java 实现的这个特性叫作 String 对象的不可变性,即 String 对象一旦创建成功,就不能再对它进行改变。

优点

  • 保证 String 对象的安全性。假设 String 对象是可变的,那么 String 对象将可能被恶意修改。

  • 保证 hash 属性值不会频繁变更,确保了唯一性,使得类似 HashMap 容器才能实现相应的 key-value 缓存功能。

  • 可以实现字符串常量池。在 Java 中,通常有两种创建字符串对象的方式,一种是通过字符串常量的方式创建,如 String str=“abc”;另一种是字符串变量通过 new 形式的创建,如 String str = new String(“abc”)。

当代码中使用第一种方式创建字符串对象时,JVM 首先会检查该对象是否在字符串常量池中,如果在,就返回该对象引用,否则新的字符串将在常量池中被创建。这种方式可以减少同一个值的字符串对象的重复创建,节约内存。

String str = new String(“abc”) 这种方式,首先在编译类文件时,"abc"常量字符串将会放入到常量结构中,在类加载时,“abc"将会在常量池中创建;其次,在调用 new 时,JVM 命令将会调用 String 的构造函数,同时引用常量池中的"abc” 字符串,在堆内存中创建一个 String 对象;最后,str 将引用 String 对象。

使用

字符串常量的累计


  public static void main(String[] args) {
        //字符串常量的累计
        
        String s = "a" + "b" + "c";

        System.out.println(s);

    }

首先会生成 a 对象,再生成 ab 对象,最后生成 abc 对象,从理论上来说,这段代码是低效的。

实际运行中,发现只有一个对象生成

查看字节码,编译器自动优化了这行代码


//  public static void main(java.lang.String[]);
//    descriptor: ([Ljava/lang/String;)V
//    flags: ACC_PUBLIC, ACC_STATIC
//    Code:
//      stack=2, locals=2, args_size=1
//         0: ldc           #2                  // String abc
//         2: astore_1
//         3: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
//         6: aload_1
//         7: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
//        10: return

字符串变量的累计



    public static void main(String[] args) {

        //字符串变量的累计
        String str = "abcdef";

        for(int i=0; i<1000; i++) {
            str = str + i;
        }

    }

反编译class文件:


//public class T5
//{
//
//    public T5()
//    {
//    }
//
//    public static void main(String args[])
//    {
//        String str = "abcdef";
//        for(int i = 0; i < 1000; i++)
//            str = (new StringBuilder()).append(str).append(i).toString();
//
//    }

编译器同样对这段代码进行了优化。Java 在进行字符串的拼接时,偏向使用StringBuilder,这样可以提高程序的效率。

String.intern

JDK文档:


  /**
     * Returns a canonical representation for the string object.
     * <p>
     * A pool of strings, initially empty, is maintained privately by the
     * class {@code String}.
     * <p>
     * When the intern method is invoked, if the pool already contains a
     * string equal to this {@code String} object as determined by
     * the {@link #equals(Object)} method, then the string from the pool is
     * returned. Otherwise, this {@code String} object is added to the
     * pool and a reference to this {@code String} object is returned.
     * <p>
     * It follows that for any two strings {@code s} and {@code t},
     * {@code s.intern() == t.intern()} is {@code true}
     * if and only if {@code s.equals(t)} is {@code true}.
     * <p>
     * All literal strings and string-valued constant expressions are
     * interned. String literals are defined in section 3.10.5 of the
     * <cite>The Java&trade; Language Specification</cite>.
     *
     * @return  a string that has the same contents as this string, but is
     *          guaranteed to be from a pool of unique strings.
     */
    public native String intern();

从注释中看到,这个方法的作用是如果常量池 中存在当前字符串,就会直接返回当前字符串,如果常量池中没有此字符串,会将此字符串放入常量池中后再返回

例子


 public static void main(String[] args) {

        String s = new String("1");
        s.intern();
        String s2 = "1";
        System.out.println(s == s2);

        String s3 = new String("1") + new String("1");
        s3.intern();
        String s4 = "11";
        System.out.println(s3 == s4);
        /*
        false
        true
         */

    }



图示:

图2.png

图中绿色线条代表 string 对象的内容指向。 蓝色线条代表地址指向。

jdk7 的版本中,字符串常量池已经从 Perm 区移到正常的 Java Heap 区域

s3和s4字符串

**String s3 = new String(“1”) + new String(“1”);,这句代码中现在生成了2最终个对象,**是字符串常量池中的“1” 和 JAVA Heap 中的 s3引用指向的对象。中间还有2个匿名的new String(“1”)我们不去讨论它们。此时s3引用对象内容是”11”,但此时常量池中是没有 “11”对象的。

接下来s3.intern();这一句代码,是将 s3中的“11”字符串放入 String 常量池中,因为此时常量池中不存在“11”字符串,所以在常量池中生成一个 “11” 的对象,关键点是 jdk7 中常量池不在 Perm 区域了,这块做了调整。常量池中不需要再存储一份对象了,可以直接存储堆中的引用。这份引用指向 s3 引用的对象。 也就是说引用地址是相同的。

最后String s4 = “11”; 这句代码中”11”是显示声明的,因此会直接去常量池中创建,创建的时候发现已经有这个对象了,此时也就是指向 s3 引用对象的一个引用。所以 s4 引用就指向和 s3 一样了。因此最后的比较 s3 == s4 是 true

s 和 s2 对象

String s = new String(“1”); 第一句代码,生成了2个对象。常量池中的“1” 和 JAVA Heap 中的字符串对象。s.intern(); 这一句是 s 对象去常量池中寻找后发现 “1” 已经在常量池里了。

接下来String s2 = “1”; 这句代码是生成一个 s2的引用指向常量池中的“1”对象。 结果就是 s 和 s2 的引用地址明显不同

调整下代码:



 public static void main(String[] args) {

        String s = new String("1");
        String s2 = "1";
        s.intern();
        System.out.println(s == s2);

        String s3 = new String("1") + new String("1");
        String s4 = "11";
        s3.intern();
        System.out.println(s3 == s4);
        /*

        false
        false
         */

    }

图示:
图3.png

图中绿色线条代表 string 对象的内容指向。 蓝色线条代表地址指向。

第一段代码和第二段代码的改变就是 s3.intern(); 的顺序是放在String s4 = “11”;后了。这样,首先执行String s4 = “11”;声明 s4 的时候常量池中是不存在“11”对象的,执行完毕后,“11“对象是 s4 声明产生的新对象。然后再执行s3.intern();时,常量池中“11”对象已经存在了,因此 s3 和 s4 的引用是不同的。

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

参考资料

https://tech.meituan.com/2014/03/06/in-depth-understanding-string-intern.html

SAP_MM_配额安排_PA认证总结 配额安排是企业进行供应商管理的一种方式。通过配额管理,企业可以与多家供应商保持业务往来,以保证某些紧缺原材料的正常供货。此外,企业也可以通过不同的配额比例,提高供应商优化服务、降低价格的积极性。 阅读详情

相关推荐

2026年7月19日 从可插拔到共封装:技术路线研究报告

AI 算力的爆发正在重写数据中心光互连的技术路线。本报告对当前并存的四代光互连架构——

weixin_51184047的博客 582

String详解

这篇博客主要介绍了String字符串,包括在内存中的存储原理和常用的方法。

weixin_43215305的博客 2695

掌控板玩板指南1:初识掌控板、扩展板、Mind+编辑器

掌控板、I/O扩展板入门

好乐无荒之地 1万+

【java源码阅读】String

* String是常量,在创建后无法更改,String等价于字符数组,StringBuffer提供可变String * 实现Serializable、Comparable等接口 * 底层是byte[],字节数组 * String的构造函数:1、传入String str,则拷贝str,2、传入char[],则调用toBytes[],3、当然也可以直接传入byte[]数组,可以处理 ...

zfeiyu的博客 257

点云入门笔记(一):点云数据及获取

点云概念: 点云是某个坐标系下的点的数据集。点包含了丰富的信息,包括三维坐标 X,Y,Z、颜色、分类值、强度值、时间等等。

wc19862274581的博客 2万+

FPGA实战 —— 基于UART的多设备串口通信系统设计

本文深入探讨了基于FPGA的多设备UART串口通信系统设计。针对工业控制与物联网应用中一对多通信的需求,文章对比了共享总线式、多路独立式等硬件连接方案,并详细阐述了可配置UART IP核、波特率自适应算法以及多路数据仲裁与分发逻辑等核心设计要点。最后,通过一个四传感器采集节点的实战案例,展示了从硬件连接到Verilog代码实现的完整系统构建过程。

weixin_29172963的博客 232

深入了解String

1 String 1.1 String类的源码 public final class String implements java.io.Serializable, Comparable<String>, CharSequence { // The value is used for character storage,用字节数组进行存储 pri...

ZoharAndroid的博客 354

AutoSAR RTE调度机制揭秘:从定时器事件到Runnable执行的完整流程

本文深入解析了AutoSAR RTE(运行时环境)的核心调度机制,详细阐述了从定时器事件触发到Runnable(可运行实体)执行的完整流程。通过剖析Rte_Start()函数、OS任务与警报的交互,以及事件驱动循环,揭示了RTE如何作为幕后指挥家,高效、可靠地协调软件组件间的周期性任务执行,是打通AutoSAR应用开发的关键。

weixin_29169899的博客 226

java中关于string的理解

java中关于String的理解前言这是一个老生常谈的问题了,也是技术面试中针对初学者经常被问到的问题,这里就根据自己的理解做下规整,希望可以帮助更多的人,如果觉得哪里说得不对,请在下方留言,验证问题后我会及时更正。String的特征在讲解String特征之前,需要介绍一下关于String至关重要的概念:字符串常量池。 在上篇的文章中讲述了java中的数据存储结构,不明白的童鞋可以看下: java

stormCoder的博客 622

VScode中配置 C/C++ 环境,超级详细,问题分析全面,绝对好用

VScode中配置 C/C++ 环境,超级详细,问题分析全面,绝对好用 VScode中配置 C/C++ 环境 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。 1. 下载编辑器VScode 1.官网:https://code.visualstudio.com/ 2. 安装VScode(建议附加任务全部勾选; 2. 下载编译器MinGW并解压 官网页面:https://www.mi

m0_46147064的博客 8万+

英飞凌TC3xx DSADC旋变软解码实战:从示波器波形到VX1000数据,手把手教你避坑

本文详细介绍了英飞凌TC3xx系列微控制器的DSADC模块在电机旋变软解码中的实战应用。从示波器波形分析到VX1000数据采集,提供了一套完整的调试方法论,帮助工程师快速定位和解决常见问题,提升解码精度和系统性能。

weixin_30598225的博客 517

java string 变量_java中String对象和String变量

java中String对象和String变量(2011-12-27 20:40:27)标签:最近在论坛上看到关于String s = new String("XYZ") + new String("XYZ");到底创建几个对象的讨论,觉得比较有意思,在此总结一下。在JAVA中除了8种基本类型之外,其他的都是类对象及其引用。所以 "XYZ"在JAVA中是一个String对象,对于String类对象来...

weixin_42522964的博客 666

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Java中List,String,String[]之间进行转换

String转换List package string; import com.google.common.base.Splitter; import com.google.common.collect.Lists; import org.apache.commons.lang3.StringUtils; import java.util.ArrayList; import java.ut...

小老弟的博客 8110

Camera2Demo

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

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Java String到int,Java int到String

Today we will look at Java String to int conversion and then java int to String conversion. Java provides several ways to convert String to int and int to String. 今天,我们将看一下Java String到int的转换,然后是java i...

从零开始的教程世界 409

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

java中String是类_java中String是对象还是类?详解java中的String

有很多人搞不懂对象和类的定义。比如说java中String到底是对象还是类呢?有人说String既可以说是类,也可以说是对象。其实他这么说也没问题,类和对象其实都是一个抽象的概念。我们可以把一类东西归集在一起,起一个名字,什么类,专门做什么事的,但是我们也可以说它是一个对象……所以说String既可以说是类,也可以说是对象。但是如果你要深究,比如小编就饿深究了一下,我发现在java.lan...

weixin_28998775的博客 1407

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 所有方法

下面是String类支持的方法,更多详细,参看Java API文档: SN(序号) 方法描述 1 char charAt(int index) 返回指定索引处的 char 值。 2 int compareTo(Object o) 把这个字符串和另一个对象比较。 3 int compareTo(String an

红叶岭谷的博客 1110

Java string和 String,理解Java String和String Pool

本文转载自:http://blog.sina.com.cn/s/blog_5203f6ce0100tiux.html要理解 java中String的运作方式,必须明确一点:String是一个非可变类(immutable)。什么是非可变类呢?简单说来,非可变类的实例是不能被修改的,每个实例中包含的信息都必须在该实例创建的时候就提供出来,并且在对象的整个生存周期内固定不变。java为什么要把Stri...

weixin_34475212的博客 329

Java String—String创建的方式

1. String创建的两种方式 String str = "mcdull"; String str1 = str; String str2 = new String("mcdull"); System.out.println(str == str1); System.out.println(str == str2); 输出结果:true、false。 为什么会这样?原因是 str2 使用 new String 时一定会在堆中重新创建一个内存区域,而 str1 则会直接使用了 str

mcsdnuser的博客 357

Java char转换为String,String转换为char数组

Today we will look into java char to String program. We will also learn how to convert String to a char array. 今天,我们将研究java char to String程序。 我们还将学习如何将String转换为char数组。 Java char转换为String (Java char ...

从零开始的教程世界 1559

java string 特性_Java中string的特性

一、创建。好了,知道String是非可变类以后,我们可以进一步了解String的构造方式了。创建一个Stirng对象,主要就有以下两种方式:java 代码1.String str1 = new String("abc");2.Stirng str2 = "abc";虽然两个语句都是返回一个String对象的引用,但是jvm对两者的处理方式是不一样的。对于第一种,jvm会马上在heap中创建一个St...

weixin_39875629的博客 126

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万+

JAVA中string的赋值_Java中关于String赋值的两种形式

说明:String在java中是使用频率很高的一个类,之前使用的时候并没有过多的在意,只知道有两种赋值方式,一种是采用字面值方式(String string1 = “string”;),一种是使用new关键字(String string2 = new String(“string”);)。如果使用string1==string2比较的话,你会发现结果为false,说明两者的地址并不一致,虽然我知道...

weixin_29791447的博客 1万+

Java——String类

Java中关于string类的一些简单介绍

qq_62122428的博客 1047

java中string是什么意思_java中string什么意思

Java是面向对象的编程语言,它其中包含有各种各样的名词,都有着不同的意思。Java中的string是字符串的意思,当声明了一个字符串变量时,便可以在里面存储数据。String类想要了解一个类,最好的办法就是看这个类的实现源代码,来看一下String类的源码:public final class Stringimplements java.io.Serializable, Comparable, ...

weixin_42509793的博客 5945

java的string类

30、String replaceAll(String regex,String replacement):用replacement替换所有的regex匹配项,regex很明显是个正则表达式,replacement是字符串。public String(byte[] bytes,String charsetName)':通过使用指定的字符集解码当前参数中的字节数组来构造新的String。6、int compareTo(String other):比较字符串大小,区分大小写,按照Unicode编码值比较大小;

2301_82309799的博客 666
上一篇: 静态链接
下一篇: Java-I/O学习(2)
Coder_py
博客等级 码龄10年 106粉丝 258原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值