`
yiheng
  • 浏览: 150688 次
社区版块
存档分类

代码之谜 - 为什么 jdk 中把 String 类设计成 final

    博客分类:
  • Java
阅读更多

最佳答案:

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

其它答案一:

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

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

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

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

其它答案二:

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

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

  1. private static final String x = "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%。

示例:

  1. public class Test {   
  2.     public static void main(String[] args)  {   
  3.         //    
  4.     }   
  5. }  

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

  1. public class String2 extends String{   
  2.    //..   
  3.    //...   
  4. }  

那我们的 main 也就可以写成

  1. public class Test {   
  2.     public static void main(String2[] args)  { // 注意此处   
  3.         //    
  4.     }   
  5. }  

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

另外补充一点:

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

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

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

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

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

7
11
分享到:
评论
1 楼 nodejs 2012-08-13  
这个世界这是怎么了?
http://nodejs.iteye.com/blog/1629981

相关推荐

    jdk中String类设计成final的原由

    为什么jdk中把 String 类设计成final,主要是为了“ 效率 ”和“安全性”的缘故,若 String 允许被继承, 由于它的高度被使用率, 可能会降低程序的性能,所以String被定义成final,需要了解的朋友可以参考下

    RSA+bcpkix-jdk15.zip

    复制代码其中的加密系数可以自定义,这里为:8246a46f44fc4d961e139fd70f4787d272d374532f4d2d9b7cbaad6a15a8c1301319aa6b3f30413b859351c71938aec516fa7147b69168b195e81df46b6bed7950cf3a1c719d42175f73d7c97a85d7...

    jboss-as-7.1.1.Final

    ——>【Finish】 生成的目录结构中,ejbModule目录为我们要写JAVA源代码的目录。 即EJB写在这里。 在ejbModule目录上右键【New】——>【Other】 (找到EJB,并且选择Session Bean(EJB 3.x))——>【Next】 输入:包...

    jdk1.8之后的String.intern()方法内存分析

    关于String.intern()方法,这个问题都被问烂了,有的文章在分析的时候还在用jdk1.7,jdk1.8之后内存模型发生了变化,内存的变化也会影响intern方法的执行,这里有必要写文章分析一下,请大家务必从头开始看,这样...

    java基础面试题目,常见的几个java面试题目:说一下java类集;JDK 和 JRE 有什么区别

    java基础面试题目,常见的几个...final 在 Java 中有什么作用; Java 中的 Math. round(-1. 5) 等于多少;String 属于基础的数据类型吗;String str="i"与 String str=new String("i")一样吗;如何将字符串反转;等等

    (String)字符串原理详解

    1、JDK1.8中String类的源码定义 1.1、主要的类变量如下所示: public final class String implements java.io.Serializable, Comparable, CharSequence { //存储字符串的字符数组 private final char value[]; /...

    Java 最常见的 208 道面试题:第一模块答案

    JDK 和 JRE 有什么区别? == 和 equals 的区别是什么? 两个对象的 hashCode()相同,则 equals()也一定为 true,对 吗? final 在 java 中有什么作用? java 中的 Math.round(-1.5) 等于多少? String 属于基础的...

    面向对象技术与UML课件及源代码-by 南邮-陈杨

    本书为中南大学精品教材立项项目,分为上下两篇共21章,涵盖了面向对象技术中Java开发环境配置、程序设计基础、面向对象原理以及UML的知识。本书使用的开发环境是JDK 1.6+Eclipse 3.3+Rational Rose 2003,逐步引领...

    涵盖了90%以上的面试题

    finally块中的代码什么时候被执行 Java中的异常处理机制的简单原理和应用。 java socket java序列化 JVM加载class文件的原理 双亲委派模型 为什么要自定义类加载器 如何自定义类加载器 什么是GC 内存泄漏和内存溢出...

    【05-面向对象(下)】

    •抽象类代表了一种未完成的类设计,它体现的是一种模板。 •抽象类与模板模式。 接口的概念 •接口定义的是多个类共同的行为规范,这些行为是与外部交流的通道,这就意味着接口里通常是定义一组公用的 ...

    java面试常见问题(超详细).pdf

    Java中的String类是可变的还是不可变的? Java中的equals方法和hashCode方法有什么关系? Java中什么是重载【Overloading】?什么是覆盖【Overriding】?它们有什么区别? Java中什么是多态?如何实现多态? Java中...

    javaSE代码实例

    15.1.2 外部类之内创建内部类对象 322 15.1.3 外部类之外创建内部类对象 323 15.1.4 内部类与外部类之间的成员互访 324 15.1.5 内部类与外部类的预定义对象引用this 327 15.2 局部内部类 328 15.2.1 局部...

    -互联网Java面试重点难点.rar

    4. final 在 java 中有什么作用? 5. java 中的 Math.round(-1.5) 等于多少? 6. String 属于基础的数据类型吗? 7. java 中操作字符串都有哪些类?它们之间有什么区别? 8. String str="i"与 String str=new ...

    SpringMVC使用JSR-303进行验证Bean.docx

    一、准备校验时使用的JARvalidation-api-1.1.0.Final.jar:JDK的接口;hibernate-validator-5.2.4.Final.jar是对上述接口的实现;或者在Maven中添加依赖:1.<dependency> 2. <groupId>org.hibernate</groupId> 3. ...

    JAVA面试题最全集

    37.classloader中,JDK的API、Classpath中的同web-inf中的class加载方式有什么区别? 38.列举三种以上垃圾回收算法,并比较其优缺点? 39.编写代码实现一个线程池 40.描述一下JVM加载class文件的原理机制? 41....

    LBLogger java日志记录信息

    MyLogger为工厂类,提供两种日志: /** * 获取按日期循环日志 * @param path String 路径; 为null 去 user.dir 目录。 * @param filename String 文件名称: 自动在后面追加 filename_YYYY-MM-DD.LOG, * @...

    java面试宝典2012版.pdf

    JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类? 73、字节流与字符流的区别 74、什么是java序列化,如何实现java序列化?或者请解释Serializable接口的作用。 75、描述一下JVM加载class...

    java面试宝典

    47、在java 中一个类被声明为final 类型,表示了什么意思? 12 48、下面哪些类可以被继承? 12 49、指出下面程序的运行结果: 【基础】 13 52、关于内部类: 13 53、数据类型之间的转换: 14 54、字符串操作:如何实现...

    red5连接池

    json-lib-2.4-jdk15.jar mysql-connector-java-5.1.9.jar spring-dao.jar spring-jdbc.jar 2,修改项目目录下的:red5-web.properties 添加:db.driver=com.mysql.jdbc.Driver db.url=jdbc:mysql://localhost:...

    Java面试宝典-经典

    JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类? 49 73、字节流与字符流的区别 50 74、什么是java序列化,如何实现java序列化?或者请解释Serializable接口的作用。 51 75、描述一下JVM加载...

Global site tag (gtag.js) - Google Analytics