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 中的键往往都使用字符串。

上一篇:JS数组和对象的浅拷贝和深拷贝


下一篇:apache配置Options详解