String类可以被继承吗?我们来聊聊final关键字!
String类可以被继承吗?我们来聊聊final关键字!
String在java基础知识中绝对是个重点知识,关于String的一些问题也是非常的多,而且牵涉到内存等高级知识,在面试中也是经常被考察的一个点,那么我们今天就来一起讨论下这个String类是否可以被继承呢?以及为什么呢?其中我们会谈到一个非常重要的知识点,那就是final关键字了,下面开始吧!
庆哥: 小白,你对String类的掌握如何呢?
小白: String啊,了解的应该比较基础,关于字符串常量池应该是String中比较重要的一个知识点,理解字符串常量池就可以解决String相关的一些问题了,比如经常考察的创建几个对象的问题!
庆哥: 可以,你这块记得还可以,那么我问你一个关于String相关的问题,请听题,请问String类是否可以被继承呢?
小白: ???
庆哥: 还三个问号,怎么?是不是不知道啊?
小白: 实不相瞒,我还真不知道,听到这个问题,我发现我脑子一片空白,没有任何可以调取的信息,这说明我对这个问题是真的不理解啊,还请庆哥指教啊!
String类是否可以被继承?
庆哥: 那我们就一起来看看这个问题,首先我们要知道,如果你要判断一个类是否可以被继承的话,你要知道这个类是如何被定义的,所以我们先来看看这个String类是如何被定义的
以上就是这个String类的定义方式,我们可以明显的看到一个final修饰符!
小白: 哦哦,我知道了,那么这个String类是不可以被继承的。因为被final修饰的类是不可以被继承的。
庆哥: 可以啊,这么快就get到点啦,那你知道为什么吗?
小白: 当看到被final修饰,我脑海中立马就产生了不可以被继承的想法,但是具体的原因我却又说不出来,我发现我对这个final修饰符不是很理解!
庆哥: 是的,理解这个我们需要先来了解下final这个关键字,那你知道final可以修饰什么吗?
小白: Google ing...
哦哦,我知道了,这个final可以修饰类,方法和成员变量,感情一个类中的东西都可以被它修饰啊。
庆哥: 是的,这个final可以用来修饰
- 类
- 成员变量
- 方法
那么接下来我们就来说一下这三个被final修饰有什么作用,首先我们就来看这个修饰类
final修饰类
我们先来写一个被final修饰的类
通过这个例子我们可以看到,被final修饰的类并不可以被继承,所以到这里我们就能知道String类是不能被继承的。
小白: 哦哦,这下知道了,被final修饰的类是不能被继承的,感觉被final修饰像是被加上一把锁一样,被禁锢了一样。
庆哥: 是的,被final修饰的类就不能被其他类继承了,所以在设计类的时候如果真的是不想这个类被其他类继承或者考虑一些安全因素,否则尽量不要把类设计成final的。
final修饰成员变量
那么,你知道final修饰成员变量有什么作用吗?
小白: 这个我好想还真知道,因为这个在平时的编码过程中有用到过,应该是被final修饰的成员变量是不可以改变的,也就是固定下来,是一个常量值了。
庆哥: 对的,确实是这样,对于变量我们知道分为基础数据类型和引用数据类型,我们还是来看一个例子吧!
在这个例子当中我们发现被final修饰的基础数据类型和引用数据类型都是不能再次赋值的,这就说明被final修饰的变量是不可变的。
final修饰方法
接下来我们就来看看这个被final修饰的方法又是怎样的?
小白: 这个让我猜猜,被final修饰的方法是不是也不能被重载覆盖啊,或者不能被调用?
庆哥: 这个嘛....我们还是一起来看看吧,小白,你读过《java编程思想》这本书吗?
小白: 这本书可是经典啊,不过,实在是有点难啃啊。
庆哥: 哈哈。经典当然难啃啦,在这本书中有这样的描述
使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最近的Java版本中,不需要使用final方法进行这些优化了。
这句话什么意思呢?也就是说,如果你不想方法在子类中被重写,你就把这个方法设置成final,我们还是来看一个例子
1 |
class Test1{ |
在这个例子中Test2继承了Test1并且覆盖了Test1的show方法,但是现在如果我不想这个方法被覆盖的话该怎么做呢?
也就是当方法被final修饰之后就不可以被覆盖了。
小白: 哦,我知道了,方法被final修饰之后不可以被子类覆盖,那么这个被final修饰的方法是否还可以正常调用以及可以重载吗?
庆哥: 可不可以我们写一个例子就知道了,看下面的例子
1 |
public class Test { |
看输出结果
小白: 知道了,被final修饰的方法可以总结如下几点
- 在子类中不能被覆盖了
- 可以实现重载
- 依旧可以正常调用
庆哥: 可以的,总结的不错,关于final的基本用法我们讨论的差不多了,看你的总结觉得你也掌握了,下面我们就来说点高级的,再问你一个问题,你知道final修饰的成员变量和普通变量有什么区别吗?
比如这俩
final String b = "hello"; String c = "hello";
小白: 这个,不就是b不可被修改,而c可以被修改嘛
庆哥: 那你看下面的代码输出结果是什么
1 |
public class Test { |
小白: 这个?有点迷啊,不应该都是true吗?
庆哥: 实际的答案是
小白: 咦,怎么第二个输出结果是false呢?这个就有点不理解了,e的最终值不也是“hello1”吗,为什么会是false呢?
final变量和普通变量的区别
庆哥: 这就牵涉到final变量和普通变量的区别了,这里的b是被final修饰的成员变量,所以当用到b的时候可以直接替换成b的值,也就是说这里的
String d = b + 1;
其实直接就等价于
String d = "hello" + 1;
这样d的值也就是“hello1”,就像你说的e的值也是“hello1”啊,但是这里不同的是什么呢?
对于d这种在编译期就可以确定下来的值,也就是说在编译阶段已经确定d就是字符串“hello1”,那么这个值就会被放到字符串常量池中,但是对于e就不一样了,因为在编译阶段c是一个变量,也就是说在编译阶段并不能确定e的值,必须等到运行时才能确定e的值是“hello1”,但是这个时候这个值因为不是在编译阶段确定下来的就不会被放到字符串常量池中,a和e的引用是不同的,自然就是false!
小白: 看来在这里我有两个知识点不是很清楚
- 对于被final修饰的变量,在用的时候是可以直接替换的,因为其本身是固定不可变的
- 只有在编译阶段确定下来的字符串才是会被放到字符串常量池中的
庆哥: 我发现现在你的总结能力日益增强啊!很强势!
小白: 庆哥,我突然想到还有一个关键字叫做static,好像表示静态的,想到这个,突然感觉有点迷,这两个有啥区别啊?
final和static
庆哥: 还记得我们一般怎样定义静态常量吗?
是不是这样
static final String NAME = "Java从0到1";
这里要记住的就是
- static同来表示唯一,独此一份,也即是静态
- final用来表示不可变
这两者一结合不就是静态常量嘛,下面举一个随机数的例子,特别能说明这个问题,你看
1 |
public class Test { |
输出结果为
你会发现,b的值始终都是一样的!
小白: 哦哦,这下知道了,那static修饰的变量可以被改变吗?
庆哥: 这个我们再测试下
1 |
public class Test { public static void main(String[] args) { |
看输出结果
我想不用多说了吧!
小白: 今天真的是让我学到好多知识啊,真是受益匪浅,感谢庆哥!
庆哥: 那你知道String类为什么不可以继承了吗?
小白: 必须知道啊,面试也不怕被问到了!
String类可以被继承吗?我们来聊聊final关键字!的更多相关文章
- Java中的String类能否被继承?为什么?
不能被继承,因为String类有final修饰符,而final修饰的类是不能被继承的. Java对String类的定义: public final class String implements ja ...
- Java中是否可以继承String类,为什么
Java中,是否可以继承String类?为什么? 答案: 不可以,因为String类有final修饰符,而final修饰的类是不能被继承的,实现细节不允许改变. public final class ...
- String类无子类
1. 关于final修饰符 参考文章: 浅析Java中的final关键字 根据程序上下文环境,Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类.非抽象类成员方法和变量 ...
- Java基础——数组应用之字符串String类
字符串String的使用 Java字符串就是Unicode字符序列,例如串“Java”就是4个Unicode字符J,a,v,a组成的. Java中没有内置的字符串类型,而是在标准Java类库中提供了一 ...
- java中String类、StringBuilder类和StringBuffer类详解
本位转载自http://www.cnblogs.com/dolphin0520/p/3778589.html 版权声明如下: 作者:海子 出处:http://www.cnblogs.com/dolp ...
- 跟着刚哥梳理java知识点——深入理解String类(九)
一.String类 想要了解一个类,最好的办法就是看这个类的实现源代码,来看一下String类的源码: public final class String implements java.io.Ser ...
- java里String类为何被设计为final
前些天面试遇到一个非常难的关于String的问题,"String为何被设计为不可变的"?类似的问题也有"String为何被设计为final?"个人认为还是前面一 ...
- 深入理解Java String类(综合)
在Java语言了中,所有类似“ABC”的字面值,都是String类的实例:String类位于java.lang包下,是Java语言的核心类,提供了字符串的比较.查找.截取.大小写转换等操作:Java语 ...
- String类——StringBuilder类的源码及内存分析(java)
相同:底层均采用字符数组value来保存字符串 区别:String类的value数组有final 修饰,指向不可改,同时private 未提供修改value数组的方法.StringBuilder类的v ...
随机推荐
- vue,一路走来(12)--父与子之间传参
今天想起一直没有记录父组件与子组件的传参问题,这在项目中一直用到. 父向子组件传参 Index.vue父组件中 <component-a :msgfromfa="(positionno ...
- git 报错
-bash: git: command not found export PATH=$PATH:/usr/local/git/bin 使用git clone出现 fatal: unable to ac ...
- systemd:在service文件中给Exec传入多个参数
原问题是这样的: 答案是这样的: 此外在使用prometheus监控mongodb时需要安装prometheus-mongodb-exporter,过程中也发现这种用法: 看看service单元文件是 ...
- standard_key.kmp
[KeyRemap]keyVersion=2B33554467=[eraseeof]S36=[bof]B33554466=[pagedn]S35=[eof]B33554465=[pageup]B10= ...
- 用Matlab的.m脚本文件处理实验室数据
找到相应的文件 findfile %1 打开文件夹 %2 拷贝第一个文件 %3 关闭当前文件,再次拷贝新的文件,直到文件末尾结束 clc clear DST_PATH_t = 'C:\Users\Ma ...
- java this的应用
package java04; /* * 当方法的局部变量和类的成员变量重名时,会根据“就近原则”,优先使用局部变量. * 如果需要访问奔雷中的成员变量,需要使用格式: this.成员变量名 * * ...
- vim/vi编辑工具实现多行注释和取消注释
转载声明:本文为转载文章 原文地址:https://blog.51cto.com/3332935/2106143 多行注释: 进入命令行模式--> 将光标移动到要注释的第一行位置--> 按 ...
- Java web入门之Http请求和响应
三层架构 web层:JSP + Servlet.Struts 2.SpringMVC service层:Spring dao层:JDBC.DBUtils.Hibernate.MyBatis form表 ...
- centos6.8安装tomcat多容器的处理办法,及安装zk、dubbo
系统环境: Linux-centosOS6.8-bit64 JDK1.8 1.Tomcat多容器的处理方案 首先,不论tomcat的版本是否有多个,路径是否相同,肯定的是可以运行多个容器. 处理以下两 ...
- 趣头条基于 Flink 的实时平台建设实践
本文由趣头条实时平台负责人席建刚分享趣头条实时平台的建设,整理者叶里君.文章将从平台的架构.Flink 现状,Flink 应用以及未来计划四部分分享. 一.平台架构 1.Flink 应用时间线 首先是 ...