java语言特点 字符串不变_面试必问:Java中String类型为什么设计成不可变的?

这几天在各大平台上都看到过这样一些帖子,全都是关于String类型对象不可变的问题,当然现在也是找工作的准备时期,因此花了一部分时间对其进行整理一下。

想要完全了解String,在这里我们需要解决以下几个问题

(1)什么是不可变对象?

(2)String如何被设计成不可变对象的?

(3)有什么办法能够改变String?

(4)JAVA语言为什么把String类型设计成不可变?

带着这些问题就可以开始今天的文章了。

一、什么是不可变对象

从字面意思也能够理解,也就是我们的创建的对象不可改变。那什么是不可变呢?为了实现创建的对象不可变,java语言要求我们需要遵守以下5条规则:

(1)类内部所有的字段都是final修饰的。

(2)类内部所有的字段都是私有的,也就是被private修饰。

(3)类不能够被集成和拓展。

(4)类不能够对外提供哪些能够修改内部状态的方法,setter方法也不行。

(5)类内部的字段如果是引用,也就是说可以指向可变对象,那我们程序员不能获取这个应用。

正是由于我们的String类型遵循了上面5条规则,所以才说String对象是不可变的。想要去了解他还是看看String类型内部长什么样子再来看上面5条规则吧。

二、String如何被设计成不可变对象的

1、疑惑一

在看之前,我们先给出一个疑惑问题,我们看下面的代码,

863633ca02ab

在文章一开始我们就说了,String对象是不可变的,这里a=张三,然后a=李四,这符合String的不可变性嘛?答案是当然符合。

863633ca02ab

从上面这张图我们可以看到,在第一次String a="张三"的时候,在堆中创建了同一个对象“张三”。后来我们在执行a="李四"的时候再内存中又创建了一个对象“李四”。也就是说我们的a仅仅只是改变了引用a指向的地址而已。

2、源码解释疑惑

既然a指向的引用地址改变了,那么其String内部肯定有一个变量,能够指向不同的实际对象,想要进一步弄清楚我们就进入其String的内部来看看。

我们在这里主要通过String类的源码来分析,看一下Java语言是如何设计,能把String类型设计成不可变的。这里给出的是jdk1.8的一部分源码。

863633ca02ab

上面最主要的是两个字段:value和hash。我们在这里主要是看value数组,hash和主题无关所以这里不再讲解了,我有专门的文章介绍hash。

我们的String对象其实在内部就是一个个字符然后存储在这个value数组里面的。但是value对外没有setValue的方法,所以整个String对象在外部看起来就是不可变的。我们画一张图解释一下上面的疑惑

863633ca02ab

现在明白了吧,也就是说真正改变引用的是value,因为value也是一个数组引用。这也可以很方便的解释下一个疑惑问题了。

3、疑惑二

既然我们的String是不可变的,好像内部还有很多substring, replace, replaceAll这些操作的方法。好像都是对String对象改变了,解释起来也很简单,我们每次的replace这些操作,其实就是在堆内存中创建了一个新的对象。然后我们的value指向不同的对象罢了。

面试的时候我们只是解释上面的原因其实不是那么尽善尽美,想要更好的去加薪去装逼,我们还需更进一步回答。

三、有什么办法能够改变String

既然有这个标题。那肯定就是有办法的,别忘了我们的反射机制,在通常情况下,他可以做出一些违反语言设计原则的事情。这也是一个技巧,每当面试官问一些违反语言设计原则的问题,你就可以拿反射来反驳他。下面我们来看一下:

863633ca02ab

我们可以通过反射来改变String。

现在我们知道它的原理以及用法,也知道可以通过反射来改变String,还有一个问题我们没有弄清楚,面试的时候你也可以反问他,来进一步提升自己的逼格。

四、JAVA语言为什么把String类型设计成不可变

这里有几个特点。

第一:在Java程序中String类型是使用最多的,这就牵扯到大量的增删改查,每次增删改差之前其实jvm需要检查一下这个String对象的安全性,就是通过hashcode,当设计成不可变对象时候,就保证了每次增删改查的hashcode的唯一性,也就可以放心的操作。

第二:网络连接地址URL,文件路径path通常情况下都是以String类型保存, 假若String不是固定不变的,将会引起各种安全隐患。就好比我们的密码不能以String的类型保存,,如果你将密码以明文的形式保存成字符串,那么它将一直留在内存中,直到垃圾收集器把它清除。而由于字符串被放在字符串缓冲池中以方便重复使用,所以它就可能在内存中被保留很长时间,而这将导致安全隐患

第三:字符串值是被保留在常量池中的,也就是说假若字符串对象允许改变,那么将会导致各种逻辑错误

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

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

相关文章

java socket android_Android:这是一份很详细的Socket使用攻略

前言Socket的使用在 Android网络编程中非常重要今天我将带大家全面了解 Socket 及 其使用方法目录示意图1.网络基础阅读本文前,请先了解 关于计算机网络基础,如计算机体系结构、TCP、UDP等知识2. Socket定义即套接字,是应用层 与 TCP/IP 协议…

内构函数java_Android JNI参数传递

Java中调用native函数传递的参数是Java数据类型,到了JNI层需进行数据类型转换,基本数据类型是在前面加个j,如int——>jint,应用数据类型除了基本数据类型的数据、Class、String和Throwable外,其余所有Java对象的数据…

java 垃圾回收机制_Java的垃圾回收机制

前言在C语言中, 程序员必须小心谨慎的处理每一项内存分配, 且内存使用完后必须手动释放曾经占用的内存空间。当内存释放不够完全时, 即存在分配但永不释放的内存块, 就会引起"内存泄漏"问题。而在Java语言中, 它给了程序员一个美好的承诺: 程序员无需管理内存, 因为J…

java闹钟程序声音_跪求高手帮忙写一个JAVA手机闹钟程序 实现添加铃声和设置多闹钟...

展开全部import java.util.*;import java.awt.*;import java.applet.*;import java.text.*;public class AlarmClock extends Applet implements Runnable{Thread timernull; //创建线程timerImage clockp,gif1,gif2,clock6,clock7; //clockp:闹钟的外壳,闹铃和e68a…

摩托罗拉ex232java_摩托罗拉ex232r如何刷机?摩托罗拉ex232r评测

导语:随着 高科 技产业的发展,手机作为一个深受影响的产业,其竞争的激烈程度也是不言而喻的。市场好比战场,而为了在这个手机战场中赢 得胜 利,不论国内或者是国外的各大厂商也都全身心的投入到新技术的开发和新产品的…

JAVA捕捉输入格式异常_Java学习(四).异常处理

异常处理任何一个软件或程序都可能在运行的过程中出现故障,问题的关键是故障出现以后如何处理?谁来处理?怎样处理?处理后系统能否恢复正常的运行?本章在介绍Java处理这类问题基本方法的基础上,讨论包含异常…

php去除html属性,PHP如何去掉所有HTML标签?

PHP如何去掉所有HTML标签?在PHP中可以使用“strip_tags()”函数将字符串中的所有HTML标签去除,该函数用于从字符串中去除HTML和 PHP标记,其语法是“strip_tags(str)”,其参数str表示要进行操作的字符串,返回值为处理后…

php获取本机root,通过PHP执行root命令

慕村225694在尝试之前&#xff0c;请阅读整个文章&#xff0c;然后进行选择。使用二进制包装器(带有suid位)的解决方案1)创建一个脚本(最好是.sh)&#xff0c;其中包含要作为root用户运行的脚本。# cat > php_shell.sh < wrapper.c < #include #include int mai…

java寂静岭 攻略,GBA版《寂静岭》HARRY篇图文流程攻略

“Play Novel: Silent Hill”是KONAMI于2001年3月21日在GBA上推出的一款文字冒险游戏&#xff0c;剧情内容取自同社的恐怖冒险游戏——Silent Hill(《寂静岭》)。游戏基本上是纯粹的文字冒险游戏&#xff0c;过程中穿插着几段动画CG作为过场&#xff0c;游戏中绝大部分的图片和…

实验一熟悉matlab环境,数字信号处理报告实验一:熟悉MATLAB环境.doc

数字信号处理报告实验一&#xff1a;熟悉MATLAB环境.doc实验一熟悉MATLAB环境一 实验目的1. 熟悉MATLAB的主要操作命令。2. 学会简单的矩阵输入和数据读写。3. 掌握简单的绘图命令。4. 用MATLAB编程并学会创建函数。5. 观察离散系统的频率响应。二 实验内容2.用MATLAB实现下列序…

微擎cloud.mod.php,微擎“could not resolve ”、“could not resolve host”系列问题处理办法...

今天一个用户跟我说模块安装出现”could not resolve host:update.we10d.cn“报错&#xff0c;昨天在整理最近十个月用户搜索关键词排行的时候也发现”could not resolve host“、”could not resolve“还是占据不小的比例的。其实这类报错的处理方法大致相同&#xff0c;都是/…

php类如何变为静态调用,PHP类中静态方法如何调用非静态方法?_后端开发

php如何将字符串转成json_后端开发php将字符串转成json的方法是&#xff1a;可以通过json_encode()函数来实现。json_encode()函数用于对变量进行JSON编码&#xff0c;该函数如果执行成功&#xff0c;则返回JSON数据&#xff0c;反之则返回FALSE。PHP类中静态方法调用非静态方法…

PHP的注释标记是什么,html的注释标记是什么

html的注释标记是“”&#xff0c;用来在源文档中插入注释&#xff0c;注释的内容不会被显示在浏览器页面上。只有在文本编辑器中&#xff0c;或浏览器的“查看源代码”选项打开文档时&#xff0c;才能看到注释。本教程操作环境&#xff1a;windows7系统、HTML5版、Dell G3电脑…

linux 监控命令行输入,监控 Linux 容器性能的命令行神器

ctop是一个新的基于命令行的工具&#xff0c;它可用于在容器层级监控进程。容器通过利用控制器组(cgroup)的资源管理功能&#xff0c;提供了操作系统层级的虚拟化环境。该工具从cgroup收集与内存、CPU、块输入输出的相关数据&#xff0c;以及拥有者、开机时间等元数据&#xff…

linux子系统停止运行,linux 系统部署spring boot 退出连接端后项目停止运行问题

准备&#xff1a;Linux系统、jar包、一个启动项目文件(starup.sh)文件名自定义1、首先需要编辑starup.sh文件&#xff0c;这里我也是从网上找了一个比较好的内容如下&#xff1a;#!/bin/bash#这里可替换为你自己的执行程序&#xff0c;其他代码无需更改APP_NAMEkaRen.jar#使用说…

linux程序mktime无权限,linux中mktime算法解析

Linux源码中的mktime算法解析我们知道&#xff0c;从CMOS中读出来的系统时间并不是time_t类型&#xff0c;而是类似于struct tm那样&#xff0c;年月日时分秒是分开存储的。那么&#xff0c;要把它转化为系统便于处理的time_t类型&#xff0c;就需要算法进行转换。我们都知道我…

linux 无线网卡连接网络连接不上去,【已解决】Ubuntu 10.04 无线网卡 无法连接

----------------------------------搬家声明------------------------------------------------------------------------搬家声明--------------------------------------【已解决】Ubuntu 10.04 无线网卡 无法连接【问题】新装的Ubuntu 10.04&#xff0c;其他一切正常&#…

Linux 软件包管理器的目的是什么,Linux软件包的管理--RPM包管理器

在Linux中如何安装、升级、卸载软件&#xff0c;是我们日常运维中重要的组成部分。接下来一CentOS6系统为例&#xff0c;讲解如何使用 RPM 包管理器&#xff0c;yum包管理器以及源码的方式来管理我们的软件包。一、相关的背景知识许多程序的源程序&#xff0c;例如使用C语言编写…

嵌入式linux mongodb,小白在Ubuntu安装mongoDB与mongo-c-driver

目的&#xff1a;本人从事嵌入式软件&#xff0c;项目中需要使用MongoDB&#xff0c;最终需要熟悉c-driver的API&#xff0c;小白在搭建环境有些浪费时间&#xff0c;故写这文章让与我同样状态的开发人员学习学习。在Ubuntu上的安装mongodb方法一&#xff1a;sudo apt-get ins…

湘潭大学-软件工程-选择判断题复习

说明 期末考试单选题和判断题占30分&#xff0c;单选20&#xff0c;判断10分 单选题 选错误的 B依靠松散组合的互联网大众是无法开发出高质量软件产品的 D、所有命名都应尽量使用缩写 C、采用团队的组织方式 D、软件需求一旦确定就不允许变化 以下哪一项是通过运行程序…