String的创建和拼接面试常考题详解

非常关键的 intern()

当intern()方法被调用的时候,如果字符串常量池中已经存在这个字符串对象了,就返回常量池中该字符串对象的地址;如果字符串常量池中不存在,就在常量池中创建一个指向该对象堆中实例的引用,并返回这个引用地址。

字符串的创建方法

String s1 = new String("hello");

首先字符串常量池中创建一个hello,在堆中创建String对象,对象的值执向为常量池中的hello,即是hello的内存地址。(如果常量池中已有hello则复用这个)

String s2 = "hello";

几个常考题

字符数组创建字符串

在字符串常量池中创建一个hello(如果常量池中已有hello则复用这个),s2变量指向常量池中的hello。

String s3 = new String(new char[]{'h','e','l','l','o'});
String s3_1 = "hello";
System.out.println(s3==s3_1);

首先在堆中创建一个字符数组,然后new一个新的字符串对象,对象利用这个字符数组进行初始化(将这个数组做了拷贝),如果是JDK9会先将char[]转为byte[]字节数组,s3所指向的字符串对象完全存储在堆中,且其字符(字节)数组与最开始创建的字符数组是不同的。

s3_1会引用字符串常量池中的 “hello” 字符串。在这个例子中,s3 不会引用与 s3_1 相同的 “hello” 对象。

注意点:一开始创建的字符数组是个匿名对象,并没有指向它的引用,执行完该行代码后意味着它可能会被垃圾收集器回收,但是即使这个字符数组在逻辑上可以被垃圾收集,实际的回收时机是由垃圾收集器决定的,可能会在之后的某个时间点发生。此外,对于这种小对象,垃圾收集的效果可能不是很明显,因为它们可能会留在新生代中,直到新生代被清理

new String()不会检查字符串常量池中是否已经有相同的字符串。而是直接在堆内存中创建一个新的字符串对象。这意味着即使字符串的内容与字符串常量池中的某个字符串相同,这个新创建的字符串对象也不会引用常量池中的字符串。

字符串拼接
String s4 = new String("1") + new String("1");
String s5 = s4.intern();
String s6 = new String("1");
String s7 = s6.intern();
System.out.println(s4==s5);
System.out.println(s6==s7); 

首先会创建两个字符串对象和常量池中字面量1(共用),创建StringBuilder对象,调用append()方法拼接字符串,然后toString(),实质是new String()创建一个新的字符串,但注意此时的11并不是字符串常量,没有存在字符串常量池中,s4所指向的字符串对象完全在堆中。

在对s4执行intern()方法时,由于常量池中没有"11",s4在堆中存放的"11"会被转移到常量池,并且s5会被赋予s4的引用,即此时都指向同一个字符串变量,即s4==s5。

而对于s6和s7,s6也是在堆中new的新的字符串对象,存储的值在常量池中,调用intern()直接返回常量池中"1"的引用给s7,所以s6!=s7。

字符串拼接:常量+常量

String s8 = "a"+"b";
String s9 = "ab";
System.out.println(s8==s9); 
// 下面的效果是一样的
final String s8_1 = "a";
final String s8_2 = "b";
String s8 = s8_1 + s8_9;

s8和s9指向的都是常量,根据常量优化机制,编译的时候就会将"a"+"b"转为"ab"存到常量池中,所以s8和s9是相同的引用。

字符串拼接:常量+变量

String s10 = "a";
String s11 = "b";
String s12 = "a" + "b";
String s13 = s1 + s2;
System.out.println(s4 == s3);//false

字符串拼接,但凡出现一个变量,由于 s10s11 是变量,Java 虚拟机不能确定它们的值在运行时是否会被改变,因此它会在堆内存中动态创建一个新的字符串对象 "ab",并将 s13 指向这个新创建的对象。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/51382.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

面试场景题系列--(4)设计一个支持敏感数据存储和传输安全的加解密平台--xunznux

文章目录 设计一个支持敏感数据存储和传输安全的加解密平台1. 设计背景2. 需求分析日常开发中的加解密程序常见问题解决方案具体来说系统主要用例过程和功能系统需求 3. 概要设计3.1 部署模型3.2 加解密调用流程 4. 详细设计4.1 密钥领域模型4.2 核心服务类设计4.3 加解密数据接…

在Spring中优雅地注入Java集合:实现依赖注入的艺术

在Spring中,可以通过多种方式注入一个Java集合(如List、Set、Map等)。Spring提供了强大的依赖注入功能,允许你以声明的方式将集合类型的依赖项注入到你的bean中。以下是一些常用的方法: 1. 使用XML配置 在Spring的XM…

WSL for Windows

1、安装 超详细Windows10/Windows11 子系统(WSL2)安装Ubuntu20.04(带桌面环境)_wsl安装ubuntu20.04-CSDN博客https://blog.csdn.net/weixin_44301630/article/details/122390018 注意,安装之后首次启动 Ubuntu 时&…

【过题记录】 7.25

Friends 所有的方案减去非法的方案就是合法的方案 对于一个人&#xff0c;找到他往后的最早出现的非法位置&#xff0c;后面所有的串都是非法 从后往前维护一个最小非法后缀即可。 #include<bits/stdc.h> using namespace std;#define int long longconst int N 1e610…

Linux——常见命令

Linux常用命令是Linux系统操作的基础&#xff0c;掌握这些命令能够极大地提高系统管理和文件操作的效率。以下是一些常用的Linux命令及其基本用法&#xff1a; 一、文件与目录操作 ls&#xff1a;列出目录内容 基本用法&#xff1a;ls [选项] [目录名]常用选项&#xff1a;-a…

【Web开发手礼】探索Web开发的魅力(十二)-Vue(2)用户动态页面

前言 主要介绍了用vue框架创建用户动态页面的具体过程&#xff0c;可以帮助学习vue框架的基本知识&#xff01;&#xff01;&#xff01;&#xff01; 用户动态页面 用户信息 用户头像 通过 Bootstrap 所提供的 .img-fluid 类让图片支持响应式布局。其原理是将 max-width: 10…

stm32 在qemu运行

stm32基础工程配置 生成stm32代码 通过cubemx 选择 stm32f407 调试功能关闭&#xff0c;设置外部时钟&#xff0c;设置串口1&#xff0c;选择makefile 工程&#xff0c;生产代码 屏蔽系统时钟配置 // SystemClock_Config 添加 发生代码 HAL_UART_Transmit(&huart1,&quo…

RocketMQ Broker组件

Apache RocketMQ 是一款分布式消息中间件&#xff0c;具有高性能、低延迟、高可靠等特点。RocketMQ 的核心组件之一是 Broker&#xff0c;它负责消息的存储、过滤、事务处理以及定时/延时消息的管理。在本文中&#xff0c;我们将详细探讨 RocketMQ Broker 的这些关键功能。 消…

在Spring Boot中使用自定义过滤器和MDC实现高级日志记录

在现代Web开发中&#xff0c;日志记录是必不可少的。通过记录日志&#xff0c;开发者可以追踪请求的流程、定位问题并进行性能调优。本文将介绍如何在Spring Boot项目中使用自定义过滤器结合MDC&#xff08;Mapped Diagnostic Context&#xff09;技术&#xff0c;实现高级日志…

三子棋小程序

一.自定义头文件(game.h) 放入源文件需要用到的标准库头文件和函数的声明 ROW 和COL为棋盘的行和列&#xff0c;三子棋嘛&#xff0c;肯定为3啦 #pragma once #include<stdio.h> #include<String.h> #include<stdlib.h> #include<time.h> #define ROW…

Redis(三)事务、管道、主从复制

事务 事务是可以执行一个命令&#xff0c;也可以执行多个命令&#xff0c;事务本质上是一组命令的集合。一个事务中的所有命令都会序列化&#xff0c;按顺序地串行化地执行而不会被其他命令插入 Redis事务和传统数据库的区别 单独的隔离操作&#xff1a;Redis的事务仅仅是保证…

Robot Operating System——深度解析监控Parameters修改的底层实现

大纲 AsyncParametersClientParameterEventHandler监控全部Parameters监控Node上Parameters的变动触发 总结 在《Robot Operating System——AsyncParametersClient监控Parameters的增删改行为》和《Robot Operating System——ParameterEventHandler监控Parameters的增删改行为…

《Java初阶数据结构》----10.<Map和Set---TreeSet和TreeMapHashSet和HashMap >

前言&#xff1a; 大家好&#xff0c;我目前在学习java。我准备利用这个暑假&#xff0c;来复习之前学过的内容&#xff0c;并整理好之前写过的博客进行发布。如果博客中有错误或者没有读懂的地方。热烈欢迎大家在评论区进行讨论&#xff01;&#xff01;&#xff01; 喜欢我文…

Linux守护进程daemon与服务service及systemctl命令的作用

在 Linux 系统的服务管理中会经常提到 daemon&#xff08;守护进程&#xff09; 与 service&#xff08;服务&#xff09;&#xff0c;守护进程 daemon 是指后台运行的进程&#xff0c;随系统启动而为应用程序提供支持&#xff0c; 而服务 service 则用于提供某种功能。 简单的…

C/C++大雪纷飞代码

目录 写在前面 C语言简介 EasyX简介 大雪纷飞 运行结果 写在后面 写在前面 本期博主给大家带来了C/C实现的大雪纷飞代码&#xff0c;一起来看看吧&#xff01; 系列推荐 序号目录直达链接1爱心代码https://want595.blog.csdn.net/article/details/1363606842李峋同款跳…

C#实现数据采集系统-Mqtt实现采集数据转发

在数据采集系统中,通过ModbusTcp采集到数据之后,再通过MQTT转发到其他应用 MQTT操作 安装MQTT mqtt介绍和环境安装 使用MQTT 在C#/Net中使用Mqtt MQTT类封装 MQTT配置类 public class MqttConfig{public string Ip {get; set;

每日任务:网络协议对比:HTTPS/HTTP与TCP/UDP

1.HTTPS和HTTP有哪些区别 HTTP 是超文本传输协议&#xff0c;信息是明文传输&#xff0c;存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷&#xff0c;在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议&#xff0c;使得报文能够加密传输。HTTP 连接建立相对简单&#x…

【LeetCode】141.环形链表、142. 环形链表 II(算法 + 图解)

Hi~&#xff01;这里是奋斗的明志&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f331;&#x1f331;个人主页&#xff1a;奋斗的明志 &#x1f331;&#x1f331;所属专栏&#xff1a;数据结构 &#x1f4da;本系列文章为个人学…

网站如何从0-1搭建部署蓝图介绍

第一步&#xff1a;网站规划 确定网站目的&#xff1a;明确网站的目标和预期的受众。内容规划&#xff1a;决定网站将包含哪些内容和功能。技术需求分析&#xff1a;确定所需的技术栈&#xff0c;例如前端和后端技术。 第二步&#xff1a;设计 草图和布局&#xff1a;绘制网…

AI学习记录 - 本地知识库实现的相关知识

在公司内部实现了个知识库&#xff0c;但这里只介绍在实现知识库的过程中用到的知识。 1、分词器 先分词&#xff0c;中文可以使用jieba分词 2、构造数据集 将词汇向量化是自然语言处理中的重要任务&#xff0c;它可以将文本数据转化为计算机能够理解和处理的向量形式。以…