String是所有语言中最常用的一个类。我们知道在Java中,String是不可变的、final的。Java在运行时也保存了一个字符串池(String pool),这使得String成为了一个特别的类。

主要是为了 “ 效率 ” 和 “ 安全性 ” 的缘故。 若 String 允许被继承, 由于它的高度被使用率, 可能会降低程序的性能,所以 String 被定义成 final。

一:String 和其他基本类型不同 , 他是个对象类型. 既然是对象类型 , 如果是在静态方法下是必须调用静态方法或值的 , 如果是非静态的方法 , 就必须要实例化.

main 函数是个 static 的. 所以String 要能像其他的基本类型一样直接被调用. 这也是为什么在 main 函数下使用 String 类型不会报告错误的原因..

一下就解释了两个心里的疑问..

以前一直觉得奇怪 ,为什么 String 是对象类型在 main 函数下却是不需要实例化的. 再次佩服 java 设计人员想得真周到.

二:当定义 String 类型的静态字段(也成类字段),可以用静态变量(非 final)代替常量(final)加快程序速度。 反之,对于原始数据类型,例如 int,也成立。

例如,你可能创建一个如下的 String 对象:

Privatestatic final Stringx="example";

对于这个静态常量(由 final 关键字标识),你使用常量的每个时候都会创建一个临时的 String 对象。 在字节代码中,编译器去掉 ”x”,代替它的是字符串 “example”, 以致每次引用 ”x” 时 VM 都会进行一次哈希表查询。

相比之下,度于静态变量 ( 非 final 关键字 ),字符串只创建一次。 仅当初始化 “x” 时, VM 才进行哈希表查询。

还有另一个解释 :

带有 final 修饰符的类是不可派生的。 在 java 核心 API 中,有许多应用 final 的例子,例如 java.lang.String。 为 String 类指定 final 防止了人们覆盖 length() 方法。

另外,如果指定一个类为 final,则该类所有的方法都是 final。 java 编译器会寻找机会内联(inline)所有的 final 方法(这和具体的编译器实现有关)。 此举能够使性能平均提高 50%。

示例:

publicclassTest{

publicstaticvoidmain(String[]args){

//

}

}

如果 String 不是 final 那么就可以继承

publicclassString2extendsString{

//..

//...

}

那我们的 main 也就可以写成

publicclassTest{

publicstaticvoidmain(String2[]args){//注意此处

//

}

}

英文参考:http://forums.sun.com/thread.jspa?threadID=636414

另外补充一点:

作用就是 final的类不能被继承,不能让别人继承有什么好处?

意义就在于,安全性,如此这般:

java 自出生那天起就是“为人民服务”,这也就是为什么java做不了病毒,也不一定非得是病毒,反正总之就是为了安全, 人家java的开发者目的就是不想让 java干这类危险的事儿,java并不是操作系统本地语言, 换句话说java必须借助操作系统本身的力量才能做事,JDK中提供的好多核心类比如 String,这类的类的内部好多方法的实现都不是java编程语言本身编写的, 好多方法都是调用的操作系统本地的API,这就是著名的“本地方法调用”,也只有这样才能做事,这种类是非常底层的, 和操作系统交流频繁的,那么如果这种类可以被继承的话,如果我们再把它的方法重写了,往操作系统内部写入一段具有恶意攻击性质的代码什么的, 这不就成了核心病毒了么?

上面所述是最重要的,另外一个方面,上面2位老兄说的也都很对, 就是不希望别人改,这个类就像一个工具一样,类的提供者给我们提供了, 就希望我们直接用就完了,不想让我们随便能改,其实说白了还是安全性, 如果随便能改了,那么java编写的程序肯定就很不稳定,你可以保证自己不乱改, 但是将来一个项目好多人来做,管不了别人,再说有时候万一疏忽了呢?他也不是估计的, 所以这个安全性是很重要的,java和C++相比,优点之一就包括这一点;

原因绝对不只有这么多,因为如果这些个核心的类都能被随便操作的话,那是很恐怖的,会出现好多好多未知的错误,莫名其妙的错误….

String类不可变性的好处:

只有当字符串是不可变的,字符串池才有可能实现。字符串池的实现可以在运行时节约很多heap空间,因为不同的字符串变量都指向池中的同一个字符串。但如果字符串是可变的,那么String interning将不能实现(译者注:String interning是指对不同的字符串仅仅只保存一个,即不会保存多个相同的字符串。),因为这样的话,如果变量改变了它的值,那么其它指向这个值的变量的值也会一起改变。

如果字符串是可变的,那么会引起很严重的安全问题。譬如,数据库的用户名、密码都是以字符串的形式传入来获得数据库的连接,或者在socket编程中,主机名和端口都是以字符串的形式传入。因为字符串是不可变的,所以它的值是不可改变的,否则黑客们可以钻到空子,改变字符串指向的对象的值,造成安全漏洞。

因为字符串是不可变的,所以是多线程安全的,同一个字符串实例可以被多个线程共享。这样便不用因为线程安全问题而使用同步。字符串自己便是线程安全的。

类加载器要用到字符串,不可变性提供了安全性,以便正确的类被加载。譬如你想加载java.sql.Connection类,而这个值被改成了myhacked.Connection,那么会对你的数据库造成不可知的破坏。

因为字符串是不可变的,所以在它创建的时候hashcode就被缓存了,不需要重新计算。这就使得字符串很适合作为Map中的键,字符串的处理速度要快过其它的键对象。这就是HashMap中的键往往都使用字符串

String被设计成不可变和不能被继承的原因相关推荐

  1. String的内存模型,为什么String被设计成不可变的

    String是Java中最常用的类,是不可变的(Immutable), 那么String是如何实现Immutable呢,String为什么要设计成不可变呢? 前言 关于String,收集一波基础,来源 ...

  2. 为什么String要设计成不可变的?

    翻译人员: 铁锚 翻译日期: 2013年11月18日 原文链接: Why string is immutable in Java ? 这是一个老生常谈的话题(This is an old yet st ...

  3. java语言特点 字符串不变_面试必问:Java中String类型为什么设计成不可变的?

    这几天在各大平台上都看到过这样一些帖子,全都是关于String类型对象不可变的问题,当然现在也是找工作的准备时期,因此花了一部分时间对其进行整理一下. 想要完全了解String,在这里我们需要解决以下 ...

  4. string replace_面试必问:String类型为什么设计成不可变的?

    这几天在各大平台上都看到过这样一些帖子,全都是关于String类型对象不可变的问题,当然现在也是找工作的准备时期,因此花了一部分时间对其进行整理一下. 想要完全了解String,在这里我们需要解决以下 ...

  5. java中数组的返回值是什么类型_面试必问:Java中String类型为什么设计成不可变的?...

    这几天在各大平台上都看到过这样一些帖子,全都是关于String类型对象不可变的问题,当然现在也是找工作的准备时期,因此花了一部分时间对其进行整理一下. 想要完全了解String,在这里我们需要解决以下 ...

  6. java 字符串连接_为什么 Java 要把字符串设计成不可变的

    String是Java中一个不可变的类,所以它一旦被实例化就无法被修改.不可变类的实例一旦创建,其成员变量的值就不能被修改.不可变类有很多优势.本文总结了为什么字符串被设计成不可变的.将涉及到内存.同 ...

  7. 为什么jdk中把String类设计成final

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 为什么j ...

  8. 为什么写了value属性 jq赋值value值不显示_为什么 String 要设计成 final,又如何设计一个不可变类呢?...

    前面聊了聊面试必考 String 的坑,具体可以细看<你真的懂 Java 的 String 吗?>,也留下了一个疑问,为什么 String 要被设计成 final 呢?其实,如果你读的认真 ...

  9. 为什么Java要把字符串设计成不可变的

    为什么80%的码农都做不了架构师?>>>    对象变量其实是一个引用,它们的值是指向对象所在的内存地址,而不是对象本身. 1.Java内存机制 Java把内存分成两种,一种叫做栈内 ...

最新文章

  1. 进程 线程 协程_进程,线程,协程那些事
  2. Linux 高可用(HA)集群之keepalived+lvs
  3. C语言 一维数组 练习
  4. Chrome好用的插件
  5. Windows Server 2012 在个人终端上使用的推荐设置
  6. AOP底层原理与注解配置详解
  7. python模块文件的扩展名不一定是py_Python导入:导入没有.py扩展名的模块?
  8. AcWing 878. 线性同余方程(拓展欧几里得)
  9. 《工作型PPT设计之道》培训心得
  10. MFC 序列化的理解及困惑点
  11. XML转换JSON格式
  12. 日紫白飞星算法_年月日时紫白飞星算法
  13. 数据库服务器使用的RAID存储架构初步介绍
  14. go语言中同一个package下的文件相互引用怎么做?
  15. Python:代码覆盖率工具coverage
  16. NAS外网远程访问的方式
  17. DevC++实现代码高亮复制进word
  18. Kaggle比赛整理
  19. 项目日志20190707
  20. 乐视汽车仅靠老贾的哽咽和激情是不够的

热门文章

  1. 真的很OK!雷军成科创板大赢家 相关投资企业3家已上市
  2. 10月5日起 部分小米红米机型将停止开发版内测公测
  3. 郭明錤:华为可能在10月开始出货鸿蒙手机
  4. Facebook合并WhatsApp和Instagram?德国:展开反垄断调查!
  5. 2018年小米竟发布了16款手机,然而最值得入手的是它!
  6. DHCP 产生僵尸进程【原创】
  7. 本地文件上传至docker容器
  8. flutter ios上踩的一个坑
  9. 安排计算机网络技术专业去电子厂专业对口吗,计算机网络技术专业好点的学校有哪些?...
  10. python中魔法函数_02 python中魔法函数