答:1.为了实现字符串池数据库
2.为了线程安全编程
3.为了实现String能够建立HashCode不可变性数组
首先你要理解final的用途,在分析String为何要用final修饰,final能够修饰类,方法和变量,而且被修饰的类或方法,被final修饰的类不能被继承,即它不能拥有本身的子类,被final修饰的方法不能被重写, final修饰的变量,不管是类属性、对象属性、形参仍是局部变量,都须要进行初始化操做。缓存
在了解final的用途后,在看String为何要被final修饰:主要是为了”安全性“和”效率“的缘故。安全
查看JDK String的源码多线程
final修饰的String,表明了String的不可继承性,final修饰的char[]表明了被存储的数据不可更改性。可是:虽然final表明了不可变,但仅仅是引用地址不可变,并不表明了数组自己不会变,请看下面图片。socket
final也能够将数组自己改变的,这个时候,起做用的还有private,正是由于二者保证了String的不可变性。线程
那么为何保证String不可变呢,由于只有当字符串是不可变的,字符串池才有可能实现。字符串池的实现能够在运行时节约不少heap空间,由于不一样的字符串变量都指向池中的同一个字符串。但若是字符串是可变的,那么String interning将不能实现,由于这样的话,若是变量改变了它的值,那么其它指向这个值的变量的值也会一块儿改变。对象
若是字符串是可变的,那么会引发很严重的安全问题。譬如,数据库的用户名、密码都是以字符串的形式传入来得到数据库的链接,或者在socket编程中,主机名和端口都是以字符串的形式传入。由于字符串是不可变的,因此它的值是不可改变的,不然黑客们能够钻到空子,改变字符串指向的对象的值,形成安全漏洞。blog
由于字符串是不可变的,因此是多线程安全的,同一个字符串实例能够被多个线程共享。这样便不用由于线程安全问题而使用同步。字符串本身即是线程安全的。
由于字符串是不可变的,因此在它建立的时候HashCode就被缓存了,不须要从新计算。这就使得字符串很适合做为Map中的键,字符串的处理速度要快过其它的键对象。这就是HashMap中的键每每都使用字符串。