对 String 字符串的理解
1、通过构造方法创建的字符串对象和直接赋值方式创建的字符串对象区别?
通过构造方法创建字符串对象是在堆内存。
直接赋值方式创建对象是在方法区的常量池。==:基本数据类型,比较的是基本数据类型的值是否相同。引用数据类型,比较的是引用数据类型的地址值是否相同。public class StringDemo {public static void main(String[] args) {String s1 = new String("hello");String s2 = "hello";System.out.println("s1==s2:" + (s1 == s2));//falseString s3 = "hello";System.out.println("s1==s3:" + (s1 == s3)); //falseSystem.out.println("s2==s3:" + (s2 == s3)); //true}
}
画图解释:
main 方法进栈开辟空间,栈内存中执行 String s1 , new String() 出来的东西肯定是在堆内存,即有一个地址值 001 指向堆内存,
但是 “hello” 字符串不是存在于堆内存中,是存在于方法区的常量池中(原因如图),在方法区中为 “hello” 开辟空间(也有地址值),地址
值 002 赋值给了堆内存中的对象,也就是说 001 地址值中包含了一个 002 地址值,所以当输出 s1 时,栈内存中 001 指向堆内存的
001,001 又包含了 002,然后堆内存中地址值 002 指向了方法区的产量池的地址值 002 ;
当 String s2 时候,没有 new 动作,所以 s2 直接是在方法区的常量池把地址值 002 拿过来,所以 s2 直接指向方法区。
但是此时两个对象,s1 存储的是地址值 001,s2 存储的是地址值 002,所以打印 false。
当 String s3时候,没有 new 动作,所以 s3 直接是在方法区的常量池把地址值 002 拿过来,所以s3直接指向方法区。
所以此时 s2和s3的地址值是一样的 002,所以打印出 true。
总之一句话,new 的动作在堆内存,直接赋值的是在方法区的常量池。
2、Java中对字符串的优化处理
我们会经常使用 String 对象,String 对象是 java 中重要的数据类型。其设计者也对String做了大量的优化工作,
这些也是String对象的特点:不变性,常量池优化和String类的final定义。
A、不变性String对象的状态在其被创建之后就不在发生变化。其设计者使用了 java 模式中不变模式。作用:在一个对象被多线程共享,而且被频繁的访问时,可以省略同步和锁的时间,从而提高性能。B、 常量池优化如同我上面的解释,即当两个 String 对象拥有同一个值的时候,它们都只是引用了常量池中的同一个地址。C、final 定义String类以final进行了修饰,主要是为了“效率” 和 “安全性” 的缘故。若 String允许被继承, 由于它的高度被使用率, 可能会降低程序的性能,所以String被定义成final。
3、String常量的累加操作优化方法。
public class StringDemo2 {public static void main(String[] args) {String s = "";long beginTime = System.currentTimeMillis();for (int i = 0; i < 100000; i++) {s += "s";}long endTime = System.currentTimeMillis();System.out.println("s拼接100000遍s耗时:"+(endTime-beginTime)+"ms");StringBuffer s1=new StringBuffer();long s1BeginTime = System.currentTimeMillis();for (int i = 0; i < 100000; i++) {s1.append("s");}long s1EndTime = System.currentTimeMillis();System.out.println("s1拼接100000遍s耗时:"+(s1EndTime-s1BeginTime)+"ms");StringBuilder s2=new StringBuilder();long s2BeginTime = System.currentTimeMillis();for (int i = 0; i < 100000; i++) {s2.append("s");}long s2EndTime = System.currentTimeMillis();System.out.println("s2拼接100000遍s耗时:"+(s2EndTime-s2BeginTime)+"ms");}
}消耗时间:s拼接100000遍s耗时:3586mss1拼接100000遍s耗时:3mss2拼接100000遍s耗时:0ms如代码所示,使用 + 拼接字符串时候,效率很低,而使用 Stringbuffer 和 StringBuilder 的 appedn() 方法时,效率
高出 + 成百上千倍,StringBuffer 的效率比 StringBuilder 低,这是由于StringBuffer实现了线程安全,效率较低不
可避免的。所以在字符串的累加操作中,建议结合线程问题选择,应避免使用+号拼接字符串。public class StringDemo3 {public static void main(String[] args) {Integer num = 0;int loop = 100000;long beginTime = System.currentTimeMillis();for (int i = 0; i < loop; i++) {String s = num + "";}long endTime = System.currentTimeMillis();System.out.println("+\"\"的方式耗时:"+(endTime-beginTime)+"ms");beginTime = System.currentTimeMillis();for (int i = 0; i < loop; i++) {String s = String.valueOf(num);}endTime = System.currentTimeMillis();System.out.println("String.valueOf()方式耗时:"+(endTime-beginTime)+"ms");beginTime = System.currentTimeMillis();for (int i = 0; i < loop; i++) {String s = num.toString();}endTime = System.currentTimeMillis();System.out.println("toString 方式耗时:"+(endTime-beginTime)+"ms");}
}消耗时间:+""的方式耗时:20msString.valueOf()方式耗时:6mstoString 方式耗时:4ms如代码所示,String.valueOf() 直接调用了底层的 Integer.toString() 方法,不过其中会先判空;+”“ 由 StringBuilder
实现,先调用了 append() 方法,然后调用了 toString() 方法获取字符串;num.toString() 直接调用了 Integer.toString()
方法,所以效率是: num.toString() 方法最快,其次是 String.valueOf(num),最后是 num+”“ 的方式。
转载于:https://www.cnblogs.com/miantiao312/p/10556042.html
对 String 字符串的理解相关推荐
- string截取某个字符串之前的_python String字符串操作
今天学习python的String字符串操作,并记录学习过程欢迎大家一起交流分享. 首先新建一个python文件命名为py3_string.py,在这个文件中进行字符串操作代码编写(如下为代码,文后有 ...
- string字符串内容倒叙_面试官:string、stringbuffer和stringbuilder都不会,我招你干什么?...
1.String类的特性 public final class Stringimplements java.io.Serializable, Comparable<String>, Cha ...
- Java String 常量池理解
Java String 常量池理解 String:字符串常量池 作为最基础的引用数据类型,Java 设计者为 String 提供了字符串常量池以提高其性能,那么字符串常量池的具体原理是什么,我们带着以 ...
- C++ string字符串的增删改查
2019独角兽企业重金招聘Python工程师标准>>> 转载请标明出处: http://blog.csdn.net/u011974987/article/details/525050 ...
- string字符串在java_java-String字符串的常用使用方法
原码 首先有个String类,看看原码(看源码的方式,我用eclipse为例.鼠标放到String上,点击Alt键,然后变成一个手的样子,再点一下,就到了String.class里面可以看原码了) 特 ...
- 【Java】String字符串的最大长度是多少?
先说结论: 对于Java字符串的最大长度,要分为2种情况进行讨论. ① 编译期:一般情况下,最大长度为65534. ② 运行期:Integer.MAX_VALUE. 接下来通过对一个字节码文件反编译来 ...
- Thinking in java-35 String 字符串
1. immutable不可改变特性 String类对象都是不可修改的.如果我们去查阅JDK文档关于String类的信息,我们将发现所有看起来修改了String内容的方法其实是返回了一个全新的对象包含 ...
- 二进制数与十进制数相互转换 string陷阱(赋值错误) 汉字分为两个字符 string123 string字符串逆转
二进制数与十进制数相互转换: 二进制数(数组)转换成十进制数的函数: BtoO(char str[]) { int lg,sum=0,j=1; lg=strlen(str)-1; for(;lg> ...
- java list 转json 字符串_JSON的String字符串与Java的List列表对象的相互转换
1.JSON的String字符串与Java的List列表对象的相互转换 在前端: 1.如果json是List对象转换的,可以直接遍历json,读取数据. 2.如果是需要把前端的List对象转换为jso ...
- C++中String 的用法 string 字符串的使用方法
转载自百度经验 :https://jingyan.baidu.com/article/20b68a8854f919796dec6265.html?qq-pf-to=pcqq.c2c string类的常 ...
最新文章
- 验证环境中的program为什么必须是automatic
- Xamarin的环境搭建Xamarin.iOS
- 频率分布直方图组距如何确定_小猿圈Python开发之绘制频率分布直方图示例
- HTML5 移动页面自适应手机屏幕四类方法
- js 获取 当天凌晨时间
- 透明大页相关内核参数_透明大内存页Hugepage支持
- linux重启网卡的命令行,linux系统重启网卡命令
- 【“互联网+”大赛华为云赛道】API命题攻略:厘清三步解题思路,用好开发工具
- 拼接字符串时的引号嵌套
- 中级程序员晋升高级程序员,只差这几个技能
- hr标签html样式,hr标签样式修改及美化(css的hr标签实现精美线条)
- 工作6年多的码农ios职位面试总结(续)
- unity中3dUI或者模型始终面向摄像机,跟随摄像机视角旋转丨视角跟随丨固定视角
- anaconda下安装pytorch超详细步骤(有问题可以在评论区提问会及时解答)
- confluence服务守护脚本
- 如何使用 React 编写无限滚动列表
- 2020 嵌入式系统原理与应用技术(第2版) 期末复习 【整理】 习题2
- 限定自身转动轴向的LookAt
- EKS学习 环境搭建方法
- 最美应用+html模板,带你秀的飞起 - 三款 H5 制作应用 - iPhone应用 - 【最美应用】...
热门文章
- MonoRail - 生命周期及controller/action/view详解(转)
- NBA球星为啥那么多顶薪?数据可视化为你揭晓真相
- 移动、复制、新增工作表
- Servlet过滤器和监听器知识总结
- IIS7.5下的web.config 404应该如何配置
- 【记录】ASP.NET MVC MapRoute .htm 不起作用
- Asp.Net 2.0 发布问题(转)
- python机器学习实战(四)
- scp 不输入密码登录
- 老男孩教育每日一题-第106天-MySQL如何授权用户admin:password远程访问权限