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

代码之谜 - 为什么 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的原由

    在Java的JDK中,`String`类被设计为`final`的主要原因在于效率和安全性。首先,让我们深入了解这两个方面。 1. **效率**: - **字符串池**:Java中的`String`类广泛用于存储和操作文本。为了提高性能,Java引入了...

    jdk6-8String类

    在Java编程语言中,`String`类是使用最频繁的类之一,它代表不可变的字符序列。在JDK的不同版本中,`String`类经历了一些优化和改进,尤其是在性能和内存管理方面。这里我们将对JDK 1.6、1.7和1.8中的`String`类进行...

    poi-3.0.1-FINAL-20070705(jb51.net).rar

    标题中的"poi-3.0.1-FINAL-20070705(jb51.net).rar"指的是Apache POI项目的一个版本,这是一个非常著名的开源库,专门用于处理Microsoft Office格式的文件,尤其是Excel。Apache POI提供了一组Java API,允许开发者...

    百度逆地址JSON解析示例(httpclient-4.5.jar+json-lib-2.4-jdk15.jar)

    在IT行业中,网络请求和数据解析是常见的任务之一。在这个示例中,我们将探讨如何使用Apache HttpClient库和Json-lib库来实现对百度逆地址转换API的调用与JSON响应的解析。这两个Java库分别是httpclient-4.5.jar和...

    Java-JDK、数据库系统开发、Web开发学习笔记

    Java-JDK、数据库系统开发、Web开发学习笔记 ...本文档涵盖了Java-JDK的基础知识,包括Object类的方法、异常类的层次结构、Java反射机制、集合类等内容,为Java开发者提供了一个全面了解Java基础知识的机会。

    jdk1.5中文api

    可以使用初始化块为类的实例变量提供默认值,即使变量声明为final也可以,如`final int i = {10};`。 7. **可变参数(Varargs)** 可变参数允许一个方法接受零个或多个相同类型的参数,如`public void print...

    Java JDK 7 实例宝典代码

    Java JDK 7 实例宝典代码集合是一份珍贵的学习资源,专门为那些想要深入理解Java 7特性和功能的开发者设计。这份压缩包包含了各种精心设计的示例代码,旨在帮助初学者和有经验的程序员更好地掌握Java编程的核心概念...

    浅谈为什么Java里面String类是不可变的

    那么,为什么 Java 语言的设计者要把 String 类型设计成不可变对象呢?下面,我们将深入探讨字符串不可变性的原因和优点。 不可变对象的定义 不可变对象指的是对象创建之后,对象的内部状态以及对象的内存指针地址...

    Java常用类与基础API-String的理解与不可变性

    ##### (1) 对String类的理解(以JDK8为例说明) **1. 环境** 本文档使用JDK 8进行演示。JDK 8的环境设置确保了所有示例代码遵循JDK 8的语法规范。在JDK 9及更高版本中,部分语法可能有所不同。 **2. 类的声明** `...

    RSA+bcpkix-jdk15.zip

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

    解决JDK1.6下的Base64报错问题

    首先,我们需要理解为什么在JDK 1.6中会遇到Base64相关的问题。在JDK 1.8及更高版本中,Java引入了`java.util.Base64`类,提供了完整的Base64编码和解码功能。但在JDK 1.6中,这个类是不存在的,因此如果直接使用高...

    JDK源码,整合所有内容

    - **对象和类**:Java是面向对象的语言,类是其核心,JDK源码中包含了大量内置类,如`Object`、`String`、`Exception`等。 - **接口与多态**:`interface`定义了类的行为规范,多态性是Java的一大特性,体现在方法...

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

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

    jdk5_64.zip

    JDK5,全称Java Development Kit 5,是Oracle公司于2004年发布的一个重要版本,它在Java语言的发展历程中扮演了至关重要的角色,引入了一系列重大的新特性,极大地提升了开发效率和代码质量。这个小巧却功能强大的...

    jboss-as-7.1.1.Final

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

    JDK API 1.6.0 中文版

    **JDK API 1.6.0 中文版** 是Java开发者的重要参考资料,它包含了Java Development Kit (JDK) 1.6.0版本的所有公开的类、接口、方法和异常等详细信息,以中文语言呈现,便于中国开发者理解和使用Java编程语言。...

    JDK7-8新特性介绍

    Stream API是JDK 8中最强大的新特性之一,它提供了一种新的方式来处理数据集合或其他类型的序列化数据。Stream API可以让你像处理SQL查询一样处理集合,这极大地简化了集合操作,尤其是复杂的集合操作。 例如,查找...

    Java软件开发实战 Java基础与案例开发详解 17-3 代码实现 共19页.pdf

    9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4...

    JDK1.6 api中文文档HTML版

    8. **枚举类型**:JDK1.5引入的枚举类型在JDK1.6中得到广泛使用,它提供了更安全的常量表示,避免了传统的public static final字段可能导致的错误。 9. **Swing和AWT**:`javax.swing`和`java.awt`包提供了图形用户...

Global site tag (gtag.js) - Google Analytics