首先看下final关键字修饰类的作用:被final修饰的类不可被继承,由此,这个问题就变成了,为什么官方不允许继承String

我们先看下官方对String类的注释的一点说明

Strings are constant; their values cannot be changed after they are created

大意为:字符串是常量,他们的值在被创建以后不能够被修改。

说到这里,我们先看下最常见的字符串对象的创建方式

String str1 = "abc";String str2 = new String("abc")//读者可以思考下以上两种方式的却别

上面两种创建String对象的区别在于:

  • 前者不会在堆中生成实例对象,而会在常量池中产生一个字符串常量
  • 后者会在堆成生成一个String类型的实例,不会在常量池中产生字符串常量



java string如何输出二进制数 java输出string地址_java string如何输出二进制数

从图中也能看出两种方式的区别



从上图中可以直观的看出同样是创建String,前者比后者更节省内存,因为使用了常量池技术,而实现常量池,就必须保证字符串不可变。假设有两个String对象分别指向常量池中的同一个字符串“abc”,如果第三个字符串改变了这个常量池的字符串,那势必会导致前两个String对象的值发生变化,进而导致程序异常。

读者可以思考一个问题:假设让你实现一个常量池,字符串可变,能实现么?

讲到这里,String类被定义成final的第一个原因大家应该都比较清楚了,我们继续分析,在JDK当中,不仅仅String类被定义成final,Integer、Long、Double等基本的包装类型都被定义成final,为什么这些基础的类型都被定义成final了呢,这里我认为最根本的一个原因在于:安全

JVM虚拟机无论再怎么跨平台,讲到底,还是基于在操作系统上实现的,这些所谓String对象,Integer对象在堆内存当中,对于操作系统而言也无非是一块内存数据,如果有一些开发者继承String对象,通过内部方法调用获取到其他String对象的信息,那会导致信息泄露,举个例子,你通过String在内存中存储了密码,我继承一个String类,获取你的密码,那这样就会有极大的安全隐患。

总结下,为什么String类被定义成final?

  1. 为了实现常量池,节省内存
  2. 为了安全

如果大家有不同意见,欢迎评论