加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

对话式情景剖析,String被Final修饰的真正原因!一篇足矣

发布时间:2019-07-16 08:16:00 所属栏目:建站 来源:佚名
导读:口试官:你好,能看得清下面这张图吗? 我:可以的。 口试官:恩,好的。呃,你能不能说一说为什么String要用final修饰? 我:final意味着不能被担任可能被重写,String类用final修饰是Java的计划职员不但愿客户端措施员担任String类,并有也许改写String类

对话式景象分解,String被Final修饰的真正缘故起因!一篇足矣

口试官:你好,能看得清下面这张图吗?

对话式景象分解,String被final修饰的真正缘故起因!一篇足矣

我:可以的。

口试官:恩,好的。呃,你能不能说一说为什么String要用final修饰?

我:final意味着不能被担任可能被重写,String类用final修饰是Java的计划职员不但愿客户端措施员担任String类,并有也许改写String类中的要领。行使String工具的最佳实践,应该是关联可能依靠,而不是担任。

口试官:恩,你还没有说到点儿上,能再睁开谈谈吗?

我:恩,好的。详细来说,String类被界说为final的首要是从两个方面来思量:安详和机能,也就是说,String被计划成final的,即思量到了安详性,也分身了机能题目。

我们可以看到上面这张图中,呈现了两个final。一个final是修饰了String类,而另一个final修饰了char数组。我们知道,String的本质现实上就是这个char数组,先来说一说 final char[] 的这个 final。

用final修饰char数组的缘故起因,还必要从我们一般的现实开拓中提及。

在一般的现实开拓中,开拓者会用到大量的字符串工具,可以说我们无时无刻不在和字符串打交道。大量的字符串被等闲的建设出来,这就涉及到一个很是严峻的题目,即机能的开销,我们知道分派给Java假造机的内存是有限的,假如不加控制的建设字符串工具,那么破绽显而易见:内存敏捷被占满,措施执行迟钝!!!于是Java的计划者回收了一种很是有用的办理步伐,即:共享字符串。共享字符串工具的要领是将字符串工具存放到假造机中的要领区内里的常量池里,差异的类,差异的要领,乃至是差异的线程,可以行使统一个字符串工具,而不必要再在内存中开发新的内存空间,从而极大的低落了内存的耗损,也晋升了措施运行服从。

因此,字符串共享是办理内存耗损以及复杂的机能开销的肯定选择。可是到这里为止,还不能表明为什么这个char数组要用final修饰。用final修饰的缘故起因来自于另一个必必要思量的题目:安详性。什么是安详性?这里的安详性,指的是线程安详性,这个很好领略,起首,我们已经确定了一个大的条件:字符串要共享,不然内存将刹时挤爆、机能将严峻降落。

可是共享的题目在于:差异的线程有也许会修改这个共享工具。

好比,thread_1正在轮回一个List,每个元素和 “abc” 举办较量,同时thread_2也在行使这个 “abc” 工具,假如thread_2改变了这个共享字符串,功效会奈何?很明明,thread_1 的功效将不行猜测!!因此,办理共享变量安详性的最好的本领,就是榨取修改共享工具,于是字符串工具的这个char数组就肯定要被 final 修饰了,由于 final 意味着榨取改变。

口试官:恩恩,没想到你的设法这么透彻!那么,这是char数组final的浸染,那为什么还要给String类自己加一个final呢?

我:恩,这也是另一个Java计划者必要思量的题目。既然共享字符数组已经确定是final的、不能改变的了,那为什么要给String也加一个final呢?缘故起因依然是机能和安详性两个方面。

可是,此时必要思量的机能和安详性却和 final char[] 的final 不太一样了。

起首,假如假设String可以被担任,那么要领也可以被重写,这内里涉及到一个C++中的观念,叫做:虚函数表。

口试官:哦?你还懂C++?

对话式景象分解,String被final修饰的真正缘故起因!一篇足矣

我: 是的。同样是面向工具的说话,Java和C++有着共通的处所。起首,虚函数是指:可以界说一个父类的指针, 其指向一个子类工具, 当通过父类的指针去挪用函数时, 可以在运行时抉择应该挪用父类的函数照旧子类的函数。虚函数是实现多态的基本。前面说了,假如String可以被担任,那么势必就会有人通过建设String引用并指向String子类工具的方法,来行使子类的要领,好比像这样写:

  1. String aa = new SubString("abcd"); 
  2. aa.length(); 

这看似没有什么题目,可是题目在于机能,前面提到了,在措施开拓进程中,字符串工具长短经常用的,上述代码在挪用工具aa.length() 时,假造机就会去虚函数表中查找并鉴定毕竟是应该挪用哪个子类的length()要领。在大量行使字符串工具的场景下,势必会低落措施运行服从。

其次又是安详性,这个安详性的表明为语义的安详性,面向工具的说话自己就要求要有清楚的语义和明晰的表达。String的各个要领都环绕着一个char数组举办,全部要领的语义都是最直接、最有用的。重写String的要领意味着:纷歧样的语义可能错误的语义。这将直接导致String举动的不确定性,行使String工具的代码将会是不安详的代码。因此,Java计划者才会榨取任何人担任String类,首要是为了String工具的操纵语义不被改变,确保行使String工具的代码是绝对安详的。

口试官:原本云云,没想到你的领略这么到位!年薪50万,来日诰日就来上班吧!

对话式景象分解,String被final修饰的真正缘故起因!一篇足矣

总结

对口试官问道为什么 String 是final的时辰,要答出两方面:第一就是final char value[] 的final ;第二就是 final class 的final。

这两个final都要紧扣安详与机能两个方面叙述。

1、final char value[] 的final 要抓住几个要害点是:value[]数组的final用于限定字符数组的修改。字符串将会被大量行使,从机能上思量迫使Java说话的计划者将 char[] 计划为共享的,又由于字符串是共享的再次迫使计划者思量到线程安详性,这才必要用final来修饰,停止并发场景下的举动不行猜测。

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读