相信大家在平时的JAVA面试中经常遇见String类型是什么?String类型是基础类型吗?今天就给大家分享下JAVA中String类型常见的面试题!
1、 == 和 equals 的区别
== 对于基本数据类型来说,是用于比较 “值”是否相等的;而对于引用类型来说,是用于比较引用地址是否相同的。
查看源码我们可以知道 Object 中也有 equals() 方法。
源代码如下:
public boolean equals(Object obj) {
return (this == obj);
}
Object 中的 equals() 方法其实就是 ==, String 重写了 equals() 方法把它修改成比较两个字符串的值是否相等。
源代码如下:
public boolean equals(Object anObject) { // 对象引用相同直接返回 true if (this == anObject) { return true; } // 判断需要对比的值是否为 String 类型,如果不是则直接返回 false if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { // 把两个字符串都转换为 char 数组对比 char v1[] = value; char v2[] = anotherString.value; int i = 0; // 循环比对两个字符串的每一个字符 while (n-- != 0) { // 如果其中有一个字符不相等就 true false,否则继续对比 if (v1[i] != v2[i]) return false; i++; } return true; } } return false;}
2、String类型可以被继承吗?
不可以,因为String类型是final类型。
源码如下:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence { //...... }
为什么这么设计呢?java之父 James Gosling 官方这样回答说:final类型他可以缓存你的结果。你在传参时不需要考虑谁会修改它的值;如果是可变类的话,则有需要重新拷贝出来一个新值进行传参,这样在性能上就会有一定的损失。
String 类设计成不可变的另一个原因是安全,当你在调用其他方法时,比如调用一些系统级操作指令之前,可能会有一系列校验,如果是可变类的话,可能在你校验过后,它的内部的值又被改变了,这样有可能会引起严重的系统崩溃问题,这是迫使 String 类设计成不可变类的一个重要原因。
总而言之final 修饰的第一个好处是安全;第二个好处是高效,以 JVM 中的字符串常量池来举例,如下两个变量:
String s1 = "古时的风筝";
String s2 = "古时的风筝";
在字符串是不可变时,我们才可以实现字符串常量池,字符串常量池可以为我们缓存字符串,提高程序的运行效率,如下图所示:
如果 String 是可变的,那当 s1 的值修改之后,s2 的值也跟着改变了,这样就和我们预期的结果不相符了,也就没有办法实现字符串常量池的功能。
3、String=new String("Rookie小强");创建了几个StringObject对象?两者区别在哪?
两个或一个对象
"Rookie小强”对应一个对象,这个对象放在字符串常量缓冲区,常量”Rookie小强”不管出现多少遍,都是缓冲区中的那一个。New String每写一遍,就创建一个新的对象,那个常量”Rookie小强”对象的内容来创建出一个新String对象。如果以前就用过“Rookie小强’”,这句代表就不会创建”Rookie小强”自己了,直接从缓冲区拿。
String 类型不可变类(immutable),所以在字符串拼接的时候如果使用 String 的话性能会很低,因此我们就需要使用另一个数据类型 StringBuffer,它提供了 append 方法和 insert 方法可用于字符串的拼接,它使用 synchronized 来保证线程安全。
源码如下:
@Override
public synchronized StringBuffer append(Object obj) {
toStringCache = null;
super.append(String.valueOf(obj));
return this;
}
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
它使用了 synchronized 来保证线程安全,所以性能不是很高,在 JDK 1.5 就有了 StringBuilder,它同样提供了 append 和 insert 的拼接方法,但它没有使用 synchronized 来修饰,因此在性能上要优于 StringBuffer,所以在非并发操作的环境下可使用 StringBuilder 来进行字符串拼接。
5、String类型是基础类型吗?
基本数据类型包括byte,int,char,long,float,double,boolean,short一共八个
Java.lang.String类是final类型的,因此不能继承,修改这个类.为了提高效率节省空间,应该用StringBuffer类。
6、String类型和JVM
String 常见的创建方式有两种,new String() 的方式和直接赋值的方式,直接赋值的方式会先去字符串常量池中查找是否已经有此值,如果有则把引用地址直接指向此值,否则会先在常量池中创建,然后再把引用指向此值;而 new String() 的方式一定会先在堆上创建一个字符串对象,然后再去常量池中查询此字符串的值是否已经存在,如果不存在会先在常量池中创建此字符串,然后把引用的值指向此字符串。
7、String类型常用的方法
以上就是常见的JAVA基础String类型的常见面试题。