JDK源码学习--String篇(二) 关于String采用final修饰的思考
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修饰的思考的更多相关文章
- JDK源码学习系列03----StringBuffer+StringBuilder
JDK源码学习系列03----StringBuffer+StringBuilder 由于前面学习了StringBuffer和StringBuilder的父类A ...
- JDK源码学习系列01----String
JDK源码学习系列01----String 写在最前面: 这是我JDK源码学习系列的第一篇博文,我知道 ...
- JDK源码学习系列02----AbstractStringBuilder
JDK源码学习系列02----AbstractStringBuilder 因为看StringBuffer 和 StringBuilder 的源码时发现两者都继承了AbstractStringBuil ...
- JDK源码学习笔记——Enum枚举使用及原理
一.为什么使用枚举 什么时候应该使用枚举呢?每当需要一组固定的常量的时候,如一周的天数.一年四季等.或者是在我们编译前就知道其包含的所有值的集合. 利用 public final static 完全可 ...
- JDK源码学习笔记——LinkedHashMap
HashMap有一个问题,就是迭代HashMap的顺序并不是HashMap放置的顺序,也就是无序. LinkedHashMap保证了元素迭代的顺序.该迭代顺序可以是插入顺序或者是访问顺序.通过维护一个 ...
- JDK源码学习系列05----LinkedList
JDK源码学习系列05----LinkedList 1.LinkedList简介 LinkedList是基于双向链表实 ...
- JDK源码学习系列04----ArrayList
JDK源码学习系列04----ArrayList 1. ...
- JDK源码学习--String篇(-)
工作三年了,用了三年的JAVA,突然发现竟然没有好好的看下JDK的源码,整天用着的String,只是大概知道怎么回事,其中的实现逻辑却是一头雾水. 知耻而后勇,加油!!! java.lang.Stri ...
- JDK源码学习--String篇(四) 终结篇
StringBuilder和StringBuffer 前面讲到String是不可变的,如果需要可变的字符串将如何使用和操作呢?JAVA提供了连个操作可变字符串的类,StringBuilder和Stri ...
随机推荐
- #include <time.h>
1 _strtime 2 difftime 3 srand 4 time 1 _strtime 函数简介 函数名: _strtime 头文件: time.h 函数原型: char * _strtime ...
- 调magento自定义模板发邮件
1. 设置邮件模板 <global> <template> <email> <custom_email_template1 module="Samp ...
- Unity CCTween UGUI 动画插件
在这简单的介绍一下 CCTween 动画插件的使用 因为GIF 制作软件不太好(网上随便下载的)所以导致效果不太好,有时间我重新制作一下 这是一下简单的效果 下面介绍怎么使用 首先 先下载 CCTwe ...
- 最简单的视音频播放演示样例4:Direct3D播放RGB(通过Texture)
===================================================== 最简单的视音频播放演示样例系列文章列表: 最简单的视音频播放演示样例1:总述 最简单的视音频 ...
- [连载]JavaScript讲义(02)--- JavaScript核心编程
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamFja2ZydWVk/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA ...
- Sizzle一步步实现所有功能(基本筛选)
第二步:实现:first,:last,:eq(),even,odd,:gt(),:lt(); :header,:root,:taget; :not(). ;(function( window ){ v ...
- 微信sdk (1)
<?php /** * wechat php test */ //define your token define("TOKEN", "weixin"); ...
- Mantis Administrator控制密码、注册不用邮件验证、添加测试员[Z]
Mantis默认安装完成后,管理员创建用户,但无法设置用户密码,只有通过邮件由用户自行修改.无法适应某些没有统一邮箱的情况,现将关闭邮箱验证方法和管理员设置用户密码方法验证通过 不用邮件验证: c ...
- C#调用短信接口(通过简单的工厂模式整合多个短信平台)
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net ...
- C++ char和string的区别
'a'是char, "a"是char string,这两者都是普通的字符和字符串,和C中没什么不同 值得注意的是后者包含两个字符,末尾有一个隐身的'\0'而:string str ...