JAVA 没有重载运算符,那么 String 类型的加法是怎么实现的,以及String类型不可变的原因和好处
1, JAVA 不具备 C++ 和 C# 一样的重载运算符 来实现类与类之间相互计算 的功能
这其实一定程度上让编程失去了代码的灵活性, 但是个人认为,这在一定程度上减少了代码异常的概率
如果可以重载运算符,当你没看见一个运算的时候,你都会怀疑这是不是调用了某个方法(个人意见)
2,String 类型加法的实现方式,其实是一个语法糖,正确的执行方式为 括号内的内容
String a = 'a';
String b = 'b';
String c = a + b; ( String c = (new StringBuilder(String.valueOf(a))).append(b).toString(); )
3,由于 String 类型的不可变性,每一次字符串的拼接都会实例化一个 StringBuilder 类,相当消耗性能
推荐字符串拼接在单线程的时候,使用 StringBuilder 多线程使用 Stringbuffer 来提高字符串拼接的性能
4,String 类型不可变的原因
4.1,设计上的考虑:JAVA 常量池的需要
4.2,性能上的考虑: java中String对象的哈希码被频繁的使用,比如在HashMap的容器中,字符串不变性保证了hash码的唯一性,
因此可以放心的进行缓存,这也是一种性能优化手段,意味着不必每次都取计算新的哈希码
4.3,安全性的考虑:String被许多的Java类(库)用来当做参数,例如 网络连接地址URL,文件路径path,
还有反射机制所需要的String参数等, 假若String不是固定不变的,将会引起各种安全隐患。
5、String类不可变的好处
5.1,只有当字符串是不可变的,字符串池才有可能实现。字符串池的实现可以在运行时节约很多heap空间,因为不同的字符串变量都指向池中的同一个字 符串。
但如果字符串是可变的,那么String interning 将不能实现(译者注:String interning是指对不同的字符串仅仅只保存一个,即不会保存多个相同的字符串。),
因为这样的话,如果变量改变了它的值,那么,其它指向这个值的变量 的值也会一起改变。
5.2,如果字符串是可变的,那么会引起很严重的安全问题。譬如,数据库的用户名、密码都是以字符串的形式传入来获得数据库的连 接,或者在socket编程中,
主机名和端口都是以字,符串的形式传入。因为字符串是不可变的,所以它的值是不可改变的,否则黑客们可以钻到空子,改变字符 串指向的对象的值,造成安全漏洞。
5.3,因为字符串是不可变的,所以是多线程安全的,同一个字符串实例可以被多个线程共享。这样便不用因为线程安全问题而使用同步。字符串自己便是线程安全的。
5.4,类加载器要用到字符串,不可变性提供了安全性,以便正确的类被加载。譬如你想加载java.sql.Connection类,而这个值被改成了myhacked.Connection,
那么会对你的数据库造成,不可知的破坏。
5.5,因为字符串是不可变的,所以在它创建的时候hashcode就被缓存了,不需要重新计算。这就使得字符串很适合作为Map中的键,字符串的处理速度要快过其它的键对象。
这就是 HashMap 中的键往往都使用字符串。
JAVA 没有重载运算符,那么 String 类型的加法是怎么实现的,以及String类型不可变的原因和好处的更多相关文章
- 编写高质量代码改善C#程序的157个建议——建议9: 习惯重载运算符
建议9: 习惯重载运算符 在开发过程中,应该习惯于使用微软提供给我们的语法特性.我想每个人都喜欢看到这样的语法特性: ; ; int total = x + y; 而不是用下面的语法来完成一样的事情: ...
- 简单重载运算符in priority_queue By cellur925
我们都知道priority_queue是大根堆. 一.变成小根堆 法一:把元素的相反数丢进堆中 法二 priority_queue<int,vector<int>,greater&l ...
- C#基础知识系列一(goto、i++、三元运算符、ref和out、String和string、重载运算符)
前言 这两天在网上看到的总结很多,尤其是博客园中的,很多很多,也给了我很多的启发,当然自己也总结过,而且有很多人也给与我一些意见和看法.不管怎样,自己还是先把所谓的基础知识加强巩固下吧. 2014年的 ...
- C++ Primer 学习笔记_63_重载运算符和转换 --转换和类类型【上】
重载运算符和转换 --转换与类类型[上] 引言: 在前面我们提到过:能够用一个实參调用的位 unsignedchar 相同范围的值,即:0到255. 这个类能够捕获下溢和上溢错误,因此使用起来比内置u ...
- C#程序编写高质量代码改善的157个建议【4-9】[TryParse比Parse、使用int?来确保值类型也可以为null、readonly和const、0值设为枚举的默认值、避免给枚举类型的元素提供显式的值、习惯重载运算符]
建议4.TryParse比Parse好 如果注意观察,除string之外的所有的基元类型.会发现它们都有两个将字符串转换为自身类型的方法:Parse和TryParse.以类型double为例. 两者最 ...
- Java - 尚学堂第八章常用类(将输入的string类型的值转为整数、浮点型、日期类型)
import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; imp ...
- 为什么Java不支持运算符重载?
另一个类似棘手的Java问题.为什么 C++ 支持运算符重载而 Java 不支持? 有人可能会说+运算符在 Java 中已被重载用于字符串连接,不要被这些论据所欺骗.与 C++ 不同,Java 不支持 ...
- c++中有些重载运算符为什么要返回引用
事实上,我们的重载运算符返回void.返回对象本身.返回对象引用都是可以的,并不是说一定要返回一个引用,只不过在不同的情况下需要不同的返回值. 那么什么情况下要返回对象的引用呢? 原因有两个: 允许进 ...
- Java的位运算符详解实例——与(&)、非(~)、或(|)、异或(^)
位运算符主要针对二进制,它包括了:“与”.“非”.“或”.“异或”.从表面上看似乎有点像逻辑运算符,但逻辑运算符是针对两个关系运算符来进行逻辑运算,而位运算符主要针对两个二进制数的位进行逻辑运算.下面 ...
随机推荐
- Rsync,Linux日志及Screen工具介绍
第十六次课 Rsync,Linux日志及Screen工具介绍 目录 一.rsync工具介绍 二.rsync常用选项 三.rsync通过ssh同步 四. rsync通过服务同步 五.linux系统日志 ...
- My SQL随记 002 登陆
如何启动MySQL服务 Step1 我的电脑右键属性找到 控制面板 选择 系统和安全 Step2 管理工具中找到服务 Step3 找到你的MySQL启动服务 如何通过黑窗口登陆退出 MySQL Ste ...
- python发送邮箱的小项目
import smtplibfrom email.mime.text import MIMEText receiver = input('输入接受者邮箱\n')subject = input('输入标 ...
- webpack配置文件--(loader)
这篇写的很详细 https://segmentfault.com/a/1190000012718374#articleHeader9 主要的配置项: test:必须 匹配需要处理的文件的扩展名 use ...
- php字符串统计次数的各种方法(转)
<?php $str = 'AbCdEfGaBcDeFgH0234;,!-AaBbCcDdEeFfGg'; $str = strtoupper($str); // 不区分大小写时,全部转换成大写 ...
- escu问题及解决
************************************************************** Qt 出现“undefined reference to `vtable ...
- supervisord.conf
; Sample supervisor config file.;; For more information on the config file, please see:; http://supe ...
- Install MariaDB on Ubuntu server
本文所描述的安装方法实用于一下软件环境 ,不能保证使用于其他版本,请参考自己实际情况调整安装方法及参数. 操作系统版本:Ubuntu Server 14.04 LTS 64bit 欲安装MariaDB ...
- github/gitee使用办法
github/gitee只要添加SSH公钥都是可以连接上的 比如把某个文件上传gitee 首先肯定要有权限 否则会一直提醒failed伤心心 接下来说常用语句 git config --list ...
- PythonStudy——函数对象 Function object
# 在python中,所有变量存放的值只要是地址,我们就称之为对象# -- 所有的变量都是用来存放地址的,所以都是对象# -- 存放整型的地址就是整型对象 | 存放函数的地址就是函数对象 | 存放文件 ...