Java中是否可以继承String类,为什么

时间:2023-03-08 15:57:51

Java中,是否可以继承String类?为什么?

答案: 不可以,因为String类有final修饰符,而final修饰的类是不能被继承的,实现细节不允许改变。

public final class String implements java.io.Serializable, Comparable<String>, CharSequence 
  • 1
  • 1

详细解析:

1. 关于final修饰符

参考文章:
浅析Java中的final关键字

根据程序上下文环境,Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类、非抽象类成员方法和变量。你可能出于两种理解而需要阻止改变:设计或效率。
  final类不能被继承,没有子类,final类中的方法默认是final的。
  final方法不能被子类的方法覆盖,但可以被继承。
  final成员变量表示常量,只能被赋值一次,赋值后值不再改变。
  final不能用于修饰构造方法。
  注意:父类的private成员方法是不能被子类方法覆盖的,因此private类型的方法默认是final类型的。

如果一个类不允许其子类覆盖某个方法,则可以把这个方法声明为final方法。
  使用final方法的原因有二:
  第一、把方法锁定,防止任何继承类修改它的意义和实现。
  第二、高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。(这点有待商榷,《Java编程思想》中对于这点存疑)

下面这段话摘自《Java编程思想》第四版第143页:

“使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最近的Java版本中,不需要使用final方法进行这些优化了。“

2. 关于String类

参考文章:
Java中的堆、栈和常量池
Java堆、栈和常量池以及相关String的详细讲解(经典中的经典)
什么是字符串常量池?
Java中的String为什么是不可变的? – String源码分析

关于String类,要了解常量池的概念

String s = new String(“xyz”);  //创建了几个对象

答案: 1个或2个, 如果”xyz”已经存在于常量池中,则只在堆中创建”xyz”对象的一个拷贝,否则还要在常量池中在创建一份

String s = "a"+"b"+"c"+"d"; //创建了几个对象

答案: 这个和JVM实现有关, 如果常量池为空,可能是1个也可能是7个等

3. 相关类: StringBuffer, StringBuilder

参考文章:
String,StringBuffer与StringBuilder的区别String StringBuilder StringBuffer 对比 总结得非常好
从源代码的角度聊聊java中StringBuffer、StringBuilder、String中的字符串拼接

String为immutable, 不可更改的,每次String对象做累加时都会创建StringBuilder对象, 效率低下。

// 程序编译期即加载完成对象s1为"ab",JVM自有优化, 效率并不差
String s1 = "a" + "b";
// 这种方式,JVM会先创建一个StringBuilder,然后通过其append方法完成累加操作,比较耗资源
// 所以在循环中做字符串累加赋值时应当使用StringBuilder或StringBuffer类
String s1 = "a";
String s2 = "b";
String s3 = s1 + s2; // 等效于 String s3 = (new StringBuilder(s1)).append(s2).toString();

StringBuffer是线程安全的
StringBuilder(5.0版本后添加的类,是StringBuffer的一个简单替换)为非线程安全的,但是效率会好些,在单线程环境中要做大量字符串累加时推荐使用该类