再谈Java的String字符串

news2024/10/2 1:27:02

        我们先看下面几个常见的面试题:

        String s1 = "abc";
        String s2 = new String("abc");
        String s3 = "a" + "b" + "c";
        String s4 = s2.intern();

        System.out.printf("s1=s2:%s\n", s1 == s2);
        System.out.printf("s1=s3:%s\n", s1 == s3);
        System.out.printf("s1=s4:%s\n", s1 == s4);

        那么请问各自的结果是什么?

        我们知道,String这个类是被final修饰,是不可变的。String的对象一旦建立,是不能更改的。我相信很多同学并不真正了解这里的不可变的真正含义,因为我开始学习java的时候,这个地方就困惑了我很久。   

有下面一段代码:

			String a ="Hello";
			a ="你好";

         那这时候我们说,这个a变了啊。其实这里我们主要是理解有误区,没有分清楚什么是对象和对象引用。我们这里的a 指的是对象引用而不是对象本身;对象在内存中是一块内存地址,而a则是一个指向该内存地址的引用。
        要比较两个对象是否相等,要用==;要比较两个对象的值是否相等,要用equals方法来判断。所以在上面额说的这个例子中,第一次赋值的时候,创建了一个“Hello”对象,a 引用指向“Hello”地址;第二次赋值的时候,又重新创建了一个对象“你好”,a 引用指向了“你好”,但“Hello”对象依然存在于内存中。    

        如下图:

        在java中,主要有两种创建字符串对象的方式,

  1. 通过字符串常量的方式来创建,如上面String s1 = "abc";
  2. 通过new形式创建,如上面的String s2 = new String("abc")。

        当使用第一种方式创建时,虚拟机会先检查该对象在常量池中是否存在,如果存在,就回返该对象的引用,如果不存在,就在常量池中创建该字符串对象。这样就能让字符串对象重复使用,降低内存;
        当使用第二种方式创建时,在类加载的时候,会在常量池中先创建“abc”,然后程序调用new的时候,会引用常量池中“abc”字符串(其实就是将堆中String对象char[]数组指向常量池对象abc中的char[])在堆中创建一个String对象,最后将s2的引用指向这个堆中String对象。  

 基于以上的String字符串基础内容的分析,我们看下最初那几个题的答案:

s1=s2:false
s1=s3:true
s1=s4:true

        第一,s1=s2为false,因为s1指向了常量池中的“abc”,而s2指向了堆内存的String对象,显然不相等;
        第二,s1=s3为false,因为在编译的时候,虚拟机给我们代码优化成了String s3 = "abc",显然s3也指向了常量池中的"abc",所以相等;
        第三,s1=s4为true,这里的intern()方法我们了解的可能不是很多。这个intern()方法,它的作用是如果字符串常量池已经包含一个等于此String对象的字符串,则返回字符串常量池中这个字符串的引用, 否则将当前String对象的引用地址(堆中)添加到字符串常量池中并返回。
所以s4也指向了常量池中的"abc",显然s1=s4。

明白了上面几个问题,也知道intern()这个方法的原理,我们再看一个题:

        String s1 = new String("5") + new String("5");
        s1.intern();
        String s2 = "55";
        System.out.printf("s1=s2:%s\n", s1 == s2);

         这个最后的结果是:s1=s2:true。这个就比较好分析了:通过加号动态生成的“55”字符串由于在运行时常量中没有该字符串的引用,所以会在调用s1.intern()时,在运行时常量池中生成一个s1的引用,当s2再次引用该字符串时,发现运行时常量池中存在相同值的字符串的引用,就直接返回s1的引用。所以s1==s2是返回的true。

 那么接下来我们再看一个题,哈哈:

        String s1 = new String("55");
        s1.intern();
        String s2 = "55";
        System.out.printf("s1=s2:%s\n", s1 == s2);

挺有意思,知识把上面的题和这个题调换一下顺序,但是结果却是:

s1=s2:false

分析如下:首先"55"在类加载的时候,已经存在静态常量池中,在new string(“55”)时,会在运行时常量池中创建一个“55”字符串的直接引用。而s1指向的并不是该引用,而是new string这个对象的引用。当s2=“55”时,返回的是运行时常量池中的引用。所以s1==s2返回false。

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

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

相关文章

IOS安全区域适配

对于 iPhone 8 和以往的 iPhone,由于屏幕规规整整的矩形,安全区就是整块屏幕。但自从苹果手机 iphoneX 发布之后,前端人员在开发移动端Web页面时,得多注意一个对 IOS 所谓安全区域范围的适配。这其实说白了就是 iphoneX 之后的苹果…

Django图书商场购物系统python毕业设计项目推荐

mysql数据库进行开发,实现了首页、个人中心、用户管理、卖家管理、图书类型管理、图书信息管理、订单管理、系统管理等内容进行管理,本系统具有良好的兼容性和适应性,为用户提供更多的网上图书商城信息,也提供了良好的平台&#x…

【APP渗透测试】 Android APP渗透测试技术实施以及工具使用(客户端服务端)

文章目录前言一、安全威胁分析二、主要风险项三、Android测试思维导图四、反编译工具五、Android客户端漏洞一、Jnaus漏洞漏洞二、数据备份配置风险漏洞漏洞三、Activity组件泄露漏洞漏洞四、BroadcastReceiver组件泄露漏洞漏洞五、允许模拟器Root环境登录漏洞漏洞六、未识别代…

LeetCode 刷题之 BFS 广度优先搜索【Python实现】

1. BFS 算法框架 BFS:用来搜索 最短路径 比较合适,如:求二叉树最小深度、最少步数、最少交换次数,一般与 队列 搭配使用,空间复杂度比 DFS 大很多DFS:适合搜索全部的解,如:寻找最短…

C++类和对象补充

目录 前言: 1. 构造函数->初始化列表 1.1 初始化列表出现原因 1.2 初始化列表写法 2. explicit关键字 2.1 explict的出现 2.2 explict的写法 3. static成员 4. 友元 4.1 友元函数 4.2 友元类 5. 内部类和匿名对象 5.1 内部类 5.2 匿名对象 前言&a…

python|第五章考试题及练习题

本篇文章是对北京理工大学嵩天老师的《Python语言程序设计》第五章考试题及练习题的学习记录。 一、考试题 1、随机密码生成 问题描述: 描述 补充编程模板中代码,完成如下功能:‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪…

Altium Designer 18中原理图DRC编译和PCB DRC检查-AD DRC

一、原理图编译 原理图检查的主要内容有: 1、元件位号冲突。也即多个元件编号相同,例如两个电容在原理图中都被命名为C2,显然肯定是无法生成PCB的。 2、网络悬浮。也即网络标号没有附着在电气走线上,一般这种是人操作失误&…

【Azure 架构师学习笔记】-Azure Logic Apps(7)- 自定义Logic Apps 调度

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Logic Apps】系列。 接上文【Azure 架构师学习笔记】-Azure Logic Apps(6)- Logic Apps调用ADF 前言 在稍微了解Logic Apps的使用之后,需要开始考虑如何调度起来。在Logic Apps里面…

ChatGPT会让6个低端岗位失业

​我是卢松松,点点上面的头像,欢迎关注我哦! 其实最近我们也是研究探索ChatGPT的商业应用方向:比如账号买卖、卖文章、论文、脚本文案、卖使用次数和时长、OEM系统等等。 目前来看,ChatGPT会让一部分低端的岗位失业&…

GEE学习笔记 七十八:干涸的洪泽湖

今天看了一篇报道直击60年一遇气象干旱:洪泽湖缩小近一半,鱼蟹受灾严重!_新华报业网(直击60年一遇气象干旱:洪泽湖缩小近一半,鱼蟹受灾严重!),既然玩GEE那就要玩出点花样…

图学习——03预备知识

本章我们介绍关于图的基础知识,包括图的定义、类型和性质、图谱理论、图的傅里叶分析等。在之后介绍图神经网络会基于这些基础知识展开, 想要简单运用图神经网络,这部分知识可以不用学。想要系统的理解图神经网络的来源和本质,这…

2019蓝桥杯真题年号字串(填空题) C语言/C++

题目描述 本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。 小明用字母 A 对应数字 11,B 对应 2,以此类推,用 Z 对应 26。对于 27 以上的数字,小明用两位或更长位的字符串来对应&…

在Windows10上安装虚拟机---VMware 17 Pro下载与安装

在Windows10上安装虚拟机---VMware下载与安装0 前言1 下载VMware 17 pro2 安装VMware 17 Pro3. 打开Vmware0 前言 电脑原生系统:Windows10虚拟机软件:VMware 17 pro准备好安装虚拟机的文件夹路径 1 下载VMware 17 pro 下载网址:VMware 官网…

采用工时表软件能为企业员工带来哪些好处

如今社会人力成本一直在攀升,企业对提升人员工作饱和度和有效分配和利用人力资源非常在意,而工时表软件是现代被广泛应用于各行业领域,用来解决项目及非项目上的人员时效管理问题的手段之一。 企业员工工时管理不一定是一件麻烦事。采用像8M…

12.centos7部署sonarqube9.6

12.centos7部署sonarqube9.6环境:sonarqube9.6Postgresql13JDK11sonarqube9.6下载地址:Postgresql13 rpm下载地址:JDK11下载地址:准备工作:修改文件句柄数(最大文件数)和用户最大进程数限制修改…

图扑数字孪生智慧机场,助推民航“四型机场“建设

前言 民航局印发的《智慧民航建设路线图》文件中,明确提出智慧机场是智慧民航的四个核心抓手之一。并从机场全域协同运行、作业与服务智能化、智慧建造与运维方面,为智慧机场的发展绘制了清晰的蓝图。 效果展示 图扑软件应用自主研发核心产品 HT for …

Vue-Router 介绍及路由原理分析

文章目录Vue-Router 路由模式单页面与传统页面跳转的区别Hash 模式History 模式abstract 模式原理解析Hash 模式原理History 模式原理路由使用引入 Vue-Router获取全局路由跳转参数的变化获取路由中带的参数重定向页面Vue-Router 路由模式 单页面与传统页面跳转的区别 单页面…

Spark Catalyst 查询优化器原理

这里我们讲解一下SparkSQL的优化器系统Catalyst,Catalyst本质就是一个SQL查询的优化器,而且和 大多数当前的大数据SQL处理引擎设计基本相同(Impala、Presto、Hive(Calcite)等)。了解Catalyst的SQL优化流程&…

Spring 入门教程详解

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…

Web3中文|1月数据显示复苏迹象,涉及NFT、DeFi、Dapp、链游……

本期看点 1、Dapp行业概述 2、DeFi的TVL增长26.8%,有回暖迹象 3、NFT市场数据飙升,交易额达9.46亿美元 4、链游使用量占行业48% 5、与去年相比,1月份区块链漏洞损失最低 区块链领域正在多元化发展,2023年1月,从各…