JDK源码学习String篇中,有一处错误,String类用final【不能被改变的】修饰,而我却写成静态的,感谢CTO-淼淼的指正。

  风一样的码农提出的String为何采用final的设计,阅读JDK源码的时候,有粗略的思考过,今天下班后又把《Thinking in Java》中关于final的内容重新看了一遍,对此写下一些关于自己的理解和想法。

 String类中final关键字的使用

  final关键字,用来描述一块数据不能被改变,两种可能理由:设计、效率

  final使用的三种情况:数据、方法、类,final修饰类,类不能被继承,final修饰方法,方法不能被重载

  final对于基本类型的修饰,使得数值不能被改变,但是用于对象引用,虽然能保证初始化指定一个对象后,就无法指向其他对象,但是对象本身确实可以修改的。

, , };
a[] = ;

  数组使用final修饰,引用地址不可改变,但是数组的数据却可以改变。

  回过头来看String的源码设计中:

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
}

  String本质上就是一个char数组,使用final修饰,虽然引用不可变,但是内容可变。

  所以 final char value[];无法保证String的不变性。

  这时候将 class String 使用final修饰,value[] 使用private授予私有访问权限。禁止String类被继承,防止被子类改写,从而保证String的不可改变,这是出于安全性的考虑。

  JAVA中参数传递的是传引用,所以多个变量可能指向的是同一个String,如果其中一个变量改变String的内容,另一个变量取到的是改变后的内容,不符合设计的初衷。

    public static String testStr(String s, String b) {
        s = b;
        b += ";
        return s;
    }

    public static void main(String[] args) {
        String s = new String("aaa");
        String b = new String("bbb");
        String ns = Test.testStr(s, b);
        System.out.println(s.toString());
    }

  关于效率的问题,涉及到JVM的处理机制,这一块不是很了解,以下内容节选自《Thinking in Java》

  在Java的早期实现中,如果将一个方法声明为final,就是同意编译器将针对该方法的所有调用都转为内嵌调用。当编译器发现一个final方法调用命令时,它会根据自己的谨慎判断,跳过插入程序代码的这种正常方式而执行方法调用机制(将参数压入栈,跳至方法代码处并执行,然后跳回并清理栈中的参数,处理返回值),并且以方法体中的实际代码的副本来代替方法调用。这将消除方法调用的开销。

源码记:苦人所不苦,能人所不能,所谓成也
声明:原创博客请在转载时保留原文链接或者在文章开头加上本人博客地址,如发现错误,欢迎批评指正。  

JDK源码学习--String篇(二) 关于String采用final修饰的思考的更多相关文章

  1. JDK源码学习系列03----StringBuffer+StringBuilder

                         JDK源码学习系列03----StringBuffer+StringBuilder 由于前面学习了StringBuffer和StringBuilder的父类A ...

  2. JDK源码学习系列01----String

                                                     JDK源码学习系列01----String 写在最前面: 这是我JDK源码学习系列的第一篇博文,我知道 ...

  3. JDK源码学习系列02----AbstractStringBuilder

     JDK源码学习系列02----AbstractStringBuilder 因为看StringBuffer 和 StringBuilder 的源码时发现两者都继承了AbstractStringBuil ...

  4. JDK源码学习笔记——Enum枚举使用及原理

    一.为什么使用枚举 什么时候应该使用枚举呢?每当需要一组固定的常量的时候,如一周的天数.一年四季等.或者是在我们编译前就知道其包含的所有值的集合. 利用 public final static 完全可 ...

  5. JDK源码学习笔记——LinkedHashMap

    HashMap有一个问题,就是迭代HashMap的顺序并不是HashMap放置的顺序,也就是无序. LinkedHashMap保证了元素迭代的顺序.该迭代顺序可以是插入顺序或者是访问顺序.通过维护一个 ...

  6. JDK源码学习系列05----LinkedList

                                             JDK源码学习系列05----LinkedList 1.LinkedList简介 LinkedList是基于双向链表实 ...

  7. JDK源码学习系列04----ArrayList

                                                                             JDK源码学习系列04----ArrayList 1. ...

  8. JDK源码学习--String篇(-)

    工作三年了,用了三年的JAVA,突然发现竟然没有好好的看下JDK的源码,整天用着的String,只是大概知道怎么回事,其中的实现逻辑却是一头雾水. 知耻而后勇,加油!!! java.lang.Stri ...

  9. JDK源码学习--String篇(四) 终结篇

    StringBuilder和StringBuffer 前面讲到String是不可变的,如果需要可变的字符串将如何使用和操作呢?JAVA提供了连个操作可变字符串的类,StringBuilder和Stri ...

随机推荐

  1. AndroidUI 引导页面的使用

    一个应用程序都少不了欢迎页面和引导页面,本文主要讲如何制作一个引页面: 首页所有的目录结构: 新建Welcome引导页面和Activity: <RelativeLayout xmlns:andr ...

  2. const和define的区别

    1.在使用const定义常量时,只能使用标量初始化; 但我们可以使用任何表达式初始化define定义的常量 2.我们可以在条件表达式中使用define定义常量,但绝对不能使用const eg: def ...

  3. nide.js(二)文件I/O

    文件I/O fs模块的基本用法 node.js中提供一个名为fs的模块来支持I/O操作,fs模块的文件I/O是对标准POSIX函数的简单封装. 1.writeFile函数的基本用法 文件I/O,写入是 ...

  4. SQL Server数据库---》增删查改

    ***数据的插入:(增) insert into 表名(字段列表) values(值列表) 如果不写字段列表就要为表添加全部的列数据 其实into也可以省略 每次只能插入一条数据 1.如果字段可以为n ...

  5. 场景:A-->B-->C 跳转到C时,要关掉B的处理方法

    场景:A-->B-->C 跳转到C时,要关掉B的处理方法:相当于从A跳转到C UIViewController *preController = [self.navigationContr ...

  6. 管理 sendmail 的邮件队列

    邮件队列是存储 sendmail 命令传送的邮件消息数据和控制文件的目录.缺省情况下,邮件队列是 /var/spool/mqueue. 邮件消息可能由于很多原因而排入队列. 例如: sendmail  ...

  7. struts2中使用json插件实现ajax交互

    json插件可以简单的实现ajax交互,避免了使用struts2-dojo-plugin.jar包时带来的struts2.x版本冲突问题.并且减少了使用ajax标签时需要的繁琐的配置包括web.xml ...

  8. 一个php创建webservice,并通过c#调用的真实实例

    最近需要用php创建webservice供C#和JAVA来调用,通过3天的搜索和尝试,终于成功在C#下调用,JAVA的调用还没开始,为防止忘记,在这里记录下来全过程. 本文参考了许多文章,文中也采用了 ...

  9. php中如何输出当前服务器的(中国)当前时间

    date_default_timezone_set('PRC');//PRC是什么?PRC是中华人民共和国啊-_- echo "今天是".date("Y年m月d日&quo ...

  10. [原创]obj-c编程17:键值观察(KVO)

    原文链接:[原创]obj-c编程17:键值观察(KVO) 系列专栏链接:objective-c 编程系列 说完了前面一篇KVC,不能不说说它的应用KVO(Key-Value Observing)喽.K ...