Java字符串网站,初探Java字符串

news/2024/5/20 4:02:56/文章来源:https://blog.csdn.net/weixin_32248781/article/details/115165769

String印象

String是java中的无处不在的类,使用也很简单。初学java,就已经有字符串是不可变的盖棺定论,解释通常是:它是final的。

不过,String是有字面量这一说法的,这是其他类型所没有的特性(除原生类型)。另外,java中也有字符串常量池这个说法,用来存储字符串字面量,不是在堆上,而是在方法区里边存在的。

字面量和常量池初探

字符串对象内部是用字符数组存储的,那么看下面的例子:

这些语句会发生什么事情? 大概是这样的:

会分配一个11长度的char数组,并在常量池分配一个由这个char数组组成的字符串,然后由m去引用这个字符串。

用n去引用常量池里边的字符串,所以和n引用的是同一个对象。

生成一个新的字符串,但内部的字符数组引用着m内部的字符数组。

同样会生成一个新的字符串,但内部的字符数组引用常量池里边的字符串内部的字符数组,意思是和u是同样的字符数组。

如果我们使用一个图来表示的话,情况就大概是这样的(使用虚线只是表示两者其实没什么特别的关系):

string1.png

结论就是,m和n是同一个对象,但m,u,v都是不同的对象,但都使用了同样的字符数组,并且用equal判断的话也会返回true。

我们可以使用反射修改字符数组来验证一下效果,可以试试下面的测试代码:

从上面的例子可以看到,经常说的字符串是不可变的,其实和其他的final类还是没什么区别,还是引用不可变的意思。 虽然String类不开放value,但同样是可以通过反射进行修改,只是通常没人这么做而已。 即使是涉及”修改”的方法,都是通过产生一个新的字符串对象来实现的,例如replace、toLower、concat等。 这样做的好处就是让字符串是一个状态不可变类,在多线程操作时没有后顾之忧。

当然,在字符串修改的时候,会产生一个新的对象,如果执行很频繁,就会导致大量对象的创建,性能问题也就随之而来了。 为了应付这个问题,通常我们会采用StringBuffer或StringBuilder类来处理。

另外,字符串常量通常是在编译的时候就确定好的,定义在类的方法区里边,也就是说,不同的类,即使用了同样的字符串, 还是属于不同的对象。所以才需要通过引用字符串常量来减少相同的字符串的数量。可以通过下面的代码来测试一下:

字符串操作细节

String类内部处理有个字符数组之外,还使用偏移位置offset和长度count, 通过offset和count来确定字符数组的一部分,这部分才是这个字符串的真正的内容。 例如,有substring这个常用方法,看下面的例子:

按照上面的说法,m,n的数据结构就如下图所示:

string2.png

可以发现,m,n,v是三个不同的字符串对象,但引用的value数组其实是同一个。 同样可以通过上述反射的代码进行验证,这里就不详述了。

但字符串操作时,可能需要修改原来的字符串数组内容或者原数组没法容纳的时候,就会使用另外一个新的数组,例如replace,concat,+等操作。另外,oracle的JDK实现中,String的构造方法,对于字符串参数只是引用部分字符数组的情况(count小于字符数组长度),采用的是拷贝新数组的方式,是比较特别的,不过这个构造方法也没什么机会使用到。

例如下面的代码:

得到的结构图如下:

string3.png

可以发现,m,u,v内部的字符数组并不是同一个,有兴趣可以试验一下。

常量池中字符串的产生

常量池中的字符串通常是通过字面量的方式产生的,就像上述m语句那样。 并且他们是在编译的时候就准备好了,类加载的时候,顺便就在常量池生成。

可以通过javap命令检查一下class的字节码,可以发现下面的高亮部分(以上面代码为例):

大家不知有没有发现,上面的图中,u和v的字符数组没有被常量池里边的字符串引用到。 原因就是这些字符串(字符数组)都是运行时生成的,而常量池里边的字符串和字符数组是完整对应上的(count等于数组长度)。

即使是字符串的内容是一样的,都不能保证是同一个字符串数组。例如下面的代码:

u和v虽然是一样内容的字符串,但内部的字符数组不是同一个。画成图的话就是这样的:

string4.png

另外有一点,如果让m声明为final,你就会发现u和v变成是同一个对象。画成图的话就是这样的:

string5.png

这应该怎么解释的?这其实都是编译器搞的鬼,因为m是final的, u直接被编译成”hello,world.”了,如果使用javap查看的话,会发现下面一段逻辑:

那么,如何让运行时产生的字符串放到常量池里边呢? 可以借助String类的intern方法。 例如下面的用法

上面我们已经知道m,n使用的是同一个字符数组,但intern方法会到常量池里边去寻找字符串”he”,如果找到的话,就直接返回该字符串, 否则就在常量池里边创建一个并返回,所以v使用的字符数组和m,n不是同一个。画成图的话就是这样的:

string6.png

字符串的内存释放问题

像字面量字符串,因为存放在常量池里边,被常量池引用着,是没法被GC的。例如下面的代码:

经过上述的操作,画成图的话就是这样的:

string7.png

而经过上面的分析,我们知道像substring、split等方法得到的结果都是引用原字符数组的。 如果某字符串很大,而且不是在常量池里存在的,当你采用substring等方法拿到一小部分新字符串之后,长期保存的话(例如用于缓存等), 会造成原来的大字符数组意外无法被GC的问题。

关于这个问题,常见的解决办法就是使用new String(String original)或java.io.StreamTokenizer类。并且在网上已经有比较广泛的讨论,大家可以去阅读一下:

结论

任何时候,比较字符串内容都应该使用equals方法

修改字符串操作,应该使用StringBuffer,StringBuilder

可以使用intern方法让运行时产生字符串的复用常量池中的字符串

字符串操作可能会复用原字符数组,在某些情况可能造成内存泄露的问题

转自http://www.importnew.com/18454.html

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

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

相关文章

新站软件快速排名_SEO优化方法总结新站快速上排名

今天我花了一下午时间,总结了新站快速排名的优化方法,从网站的建站、上线到后期的维护,步步为营,让你的网站不再愁没有收录,没有排名,哈哈,希望对大家有所帮助哦!一、新站优化与老站优化的区别(…

优化网站响应时间tomcat添加gzip

优化网站响应时间tomcat添加gzip author YHC tomcat版本要求:5.0 step 1:找到你的${tomcat}/conf/server.xml 注:${tomcat}代表你的tomcat安装路径 step 2:打开文件,添加以下红线圈住选项: 以上代码解释: [plain] view plaincopy compression"on" 打开tomcat压缩…

html网页打开慢的解决方法,真实案例讲述导致网站打开速度慢的原因及解决方法...

听到旁边的同事在说域名实名制的问题,我决定打开域名服务商的网站查看下qiuingseo.com这个域名有没有做实名认证。结果之前已经做了实名认证了,而且上次做实名认证时还有另外一个问题没有得到解决,今天决定再试一下能不能有办法解决。前段时间…

个人摄影网站 服务器,云摄影平台服务器

云摄影平台服务器 内容精选换一换当用户已在ECS服务购买GPU加速型云服务器,并且想在该云服务器上运行应用时,可以通过纳管的方式将该云服务器纳入VR云渲游平台管理。登录控制台,在服务列表中选择“计算 > VR云渲游平台”。在左侧导航栏&am…

IIS日志-网站运维的好帮手

感谢原博主!原博客地址:http://www.cnblogs.com/fish-li/p/3139366.html 对于一个需要长期维护的网站来说,如何让网站长久稳定运行是件很有意义的事情。 有些在开发阶段没有暴露的问题很有可能就在运维阶段出现了,这也是很正常的…

网站全局变灰操作方式及实现CSS代码

网站全局变灰操作方式及实现CSS代码 04-03,2020 为表达全国各族人民对抗击新冠肺炎疫情斗争牺牲烈士和逝世同胞的深切哀悼,国务院决定,2020年4月4日举行全国性哀悼活动。 为响应国务院办公厅关于为新冠肺炎疫情牺牲烈士和逝世同胞举行全国性哀悼活动的…

php spider 参数详解,利用phpspider爬取网站数据

在我们的工作中可能会涉及到要到其它网站去进行数据爬取的情况,我们这里使用phpspider这个插件来进行功能实现。1、首先,我们需要php环境,这点不用说。2、安装composer,这个网上教程很多,这里不多做赘述,一…

Hexo搭建个人博客网站

文章目录0.首先介绍一下hexo是怎么搭建的博客?一、搭建但是我在这里遇到了两个问题1.命令行报错:YAMLException: can not read a block mapping entry; a multiline key may not be an implicit key at line 10, column 7:2.登陆博客之后中文乱码二、修改主题以 hexo-theme-ne…

计算机大赛网站设计,【计算机设计大赛】网站设计类决赛圆满落幕

原标题:【计算机设计大赛】网站设计类决赛圆满落幕【计算机设计大赛】网站设计类决赛圆满落幕为引导学生正确使用和认识网络,提高我院学生的网页设计和制作水平,12月12日晚19点我院在学校c103b教室举行了以川藏旅游为主题的网站设计比赛的决赛…

将 Hexo 静态博客网站部署到阿里云服务器

本文建立在 Hexo搭建个人博客网站 基础之上。 本来是不打算将博客部署到阿里云服务器的,之前只是用服务器备案了域名然后转而投奔鹅厂的存储桶,然后用的挺爽的时候收到了一封邮件: 。。。。 好吧,我部署。 一、域名解析 (可跳过…

使用 Django + Vue.js 开发个人博客网站(完整版附源码)—— Python-课程设计-期末项目

页面展示: 源码 首页 不同板块 注册页面 登录页面 个人信息 写文章页面 文章详情页面 文章评论 本文主要讲解 Python 后端部分,由于仅仅用到了 vue 作为 js 框架并非前后端分离项目,故前端不单独介绍。 一、项目内容(做…

系统检测到您正在使用网页抓取工具访问_SEO优化:搜索引擎蜘蛛抓取异常,原来是这个原因!...

有一些网页内容优质,用户也可以正常访问,但是搜索引擎蜘蛛却无法正常访问并抓取,造成搜索结果覆盖率缺失,对搜索引擎对站点都是一种损失,百度把这种情况叫“抓取异常”。对于大量内容无法正常抓取的网站,百…

python爬取一条新闻内容_Python爬取网站新闻

准备### 本实例使用辅助工具Fiddler抓取网页数据和使用文档查看工具sublime正则过滤(也可使用其它文档编辑工具),python开发工具使用Pycharm编辑 我们选取搜狐网的新闻页面进行爬取,对搜狐新闻以列表的形式显示出来。首先我们打开…

windows论坛_《鸡站群组》-教你建站(1.1) 下载并配置windows宝塔面板

(Linux请自己参考官网教程哈)欢迎访问 鸡站论坛各位站长们好呀 欢迎来到由鸡站群组独家呈现的建站教程 本教程会围绕各大站长的需求 以各种建站源码的使用以主要内容进行教学“工欲善其事,必先利其器” 作为一位站长 我们需要建站环境对网站进…

htm怎么让图片和搜索框在同一行_【浙江四为网络】单页网站如何优化搜索引擎优化?...

【浙江四为网络】相信网站管理员会看到一个单一页面的网站,网站排名也很好。他们是怎么做到的?他们一定很好奇。事实上,单页网站比多页网站难得多。页面太固定,太简单。没有锚链接,没有内部链。所以你可以想象出难度因…

个人主页代码html_网站搭建 | 半小时内搭建GitHub Pages个人主页!

想拥有一个免费的个人主页吗?在这里,你可以发布自己的博客、自由定制网站的主题,你可以拥有极好的创作体验,它可以成为你对外的一张“名片”,体现你的品味和兴趣,还有更重要的,它是免费的、可控…

服务器能绑定任意网站吗,域名只能绑定指定备案服务器吗

域名只能绑定指定备案服务器吗 内容精选换一换负载均衡器支持两种类型的证书,服务器证书和CA证书。配置HTTPS监听器时,需要为监听器绑定服务器证书,如果开启双向认证功能,还需要绑定CA证书。服务器证书:在使用HTTPS协议…

github pages搭建网站(三)

一、个人站点 访问 https://用户名.github.io搭建步骤 (1)创建个人站点 ->新建仓库(注:仓库名必须是【用户名.github.io】)(2)在仓库下新建index.html的文件即可注意:github pages只支持静态网页仓库里面只能是.htm…

小程序搜索框_正式发布!微信小程序seo搜索优化指南!

继上次发布小程序页面搜索指导之后,微信新发布小程序seo搜索优化指南,推出新的小程序搜索标准以下是微信官方发布的具体搜索标准:1. 小程序里跳转的页面 (url) 可被直接打开。小程序页面内的跳转url是我们爬虫发现页面的重要来源,…

景安重启服务器打不开网站,如何解决网站无法访问 Apache也无法启动?

如何解决网站无法访问 Apache也无法启动?1、错误现象这是景安一个客户的案例,客户告知网站无法访问了,并且Apache也无法启动。客户的网站是基于ApacheTomcatMysql构建,于是登录景安服务器查看信息如下图。这里提示的是http.pid文件…