详解Java中的String类
1. String 是 Java 基本数据类型吗?
许多同学在学习String类时,会误认为String类是基本数据类型,因为实实在在好像有点像C语言中的字符数组,字符,那不就是基本数据类型吗?可实际上不是的.在Java中String是个表示字符串的一个类,它是由字符组成的不可变序列。尽管String在使用时表现得像基本数据类型,但它实际上是一个引用数据类型.
补充: Java中基本数据类型为byte(1字节),short(2字节),int(4字节),long(8字节),float(4字节),double(8字节),char(2字节),boolean(不固定)
需要注意的是,虽然boolean类型在逻辑上可能只占用1位,但在实际的内存存储中,JVM可能会为其分配更多的空间(例如,在数组中,每个boolean元素可能会占用一个字节)
2. String类可以被继承吗?
答案是否定的,我们去看看String的源码
发现String类是被final修饰的,所以是不可继承的.
补充: final可修饰变量,方法,类
- final修饰变量时,表示为常量,被final修饰的变量必须赋初值
- final修饰方法时,表明这个方法不可被重写.
- final修饰类时,表明这个类不可被继承.
这种设计主要是由于这几个原因:
- 字符串的不可变性:String类的不可变性使得它可以被安全地用于多线程环境下,不会出现线程安全问题。
- 字符串常量池的优化:由于字符串是不可变的,Java可以对字符串进行缓存和共享,以提高性能和节省内存。这就是通过字符串常量池来实现的,它存储了所有字符串字面量的唯一实例。
- 安全性和可靠性:String类的不可变性使得它在安全性和可靠性方面更加可靠。例如,它可以被用作Map的键,因为它的哈希值是固定的
3. new一个String类和直接赋值一个字符串有什么区别啊?
我们来看下面这一串代码,思考会有什么样的区别呢?
两个语句都会去字符串常量池中检查是否已经存在 “abc”,如果有则直接使用,如果没有则会在常量池中创建 “abc” 对象
但是不同的是,String str1 = new String(“abc”) 还会通过 new String() 在堆里创建一个 “abc” 字符串对象实例。所以后者可以理解为被前者包含。
String s = new String(“abc”)创建了几个对象?很明显,一个或两个。如果字符串常量池已经有“abc”,则是一个;否则,两个。
当字符创常量池没有 “abc”,此时会创建如下两个对象:
- 一个是字符串字面量 “abc” 所对应的、字符串常量池中的实例
- 另一个是通过 new String() 创建并初始化的,内容与"abc"相同的实例,在堆中
4.String不是不可变类吗?字符串拼接是如何实现的?
String的确是不可变的,“+”的拼接操作,其实是会生成新的对象。
例如这段代码:
在jdk1.8之前,a和b初始化时位于字符串常量池,ab拼接后的对象位于堆中。经过拼接新生成了String对象。如果拼接多次,那么会生成多个中间对象
而在Java8以后,JDK对“+”号拼接进行了优化,上面所写的拼接方式会被优化为基于StringBuilder的append方法进行处理。Java会在编译期对“+”号进行处理。
所以,通过加号拼接字符串会创建多个String对象,因此性能比StringBuilder差,就是错误的了。因为本质上加号拼接的效果最终经过编译器处理之后和StringBuilder是一致的
5.intern方法有什么作用?
源码中用英文解释了
大致意思为
- 如果当前字符串内容存在于字符串常量池(即equals()方法为true,也就是内容一样),直接返回字符串常量池中的字符串
- 否则,将此String对象添加到池中,并返回String对象的引用
6.String 和 StringBuilder,StringBuffer?
- String类:String是不可变的,使用 private final char value[] 来存储字符串,一旦创建就不能修改其值。任何对String的修改都会创建一个新的String对象。String类是线程安全的,因为它的不可变性保证了多个线程可以安全地共享String对象。然而,由于不可变性的特性,对于频繁的字符串拼接操作,会产生大量的临时对象,影响性能。
- StringBuffer类:StringBuffer是可变的,使用 char value[] 存储字符串,它的值可以被修改。为了保证线程安全性,StringBuffer的方法都使用synchronized关键字进行同步。因此,在多线程环境下,使用StringBuffer可以保证线程安全。然而,由于同步的开销,StringBuffer的性能相对较低。
- StringBuilder类:StringBuilder是StringBuffer的非线程安全版本,它的方法没有使用synchronized关键字进行同步。因此,在单线程环境下,使用StringBuilder可以获得更好的性能。然而,由于不具备线程安全性,如果在多线程环境下使用StringBuilder,需要自行保证线程安全。
标签:面试题,abc,String,StringBuilder,常见,线程,字符串,常量 From: https://blog.csdn.net/m0_65013257/article/details/139755467一般来说,在实际使用中:如果操作的数据量较小,可以使用String类。如果在多线程环境下操作大量的数据,需要保证线程安全,可以使用StringBuffer类。如果在单线程环境下操作大量的数据,可以使用StringBuilder类以,性能更好。