1、String为什么是final类?
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
打开String的源码我们发现 String class 是final的,这为什么呢?作者为甚设计成final的呢?有什么意义? 安全,高效
java语言之父James Gosling 2001年说:(不可变类和String)他会倾向于使用final,因为他能够缓存结果,当你在传参时不需要考虑谁会修改他的值,如果是可变类的话,则有可能需要重新拷贝出来一个新值进行传参,这样在性能上就会有一定损失。
迫使String设计类设计成不可变类的另一个原因是因为安全。(当你在调用其他方法,比如调用系统参数,你会有一部分校验,如果在校验过之后你的值被改变了,这样可能会造成系统崩溃)。
String 常量池
2、String的value 为什么是final char数组?
3、String都有哪些常用的方法?
equals():比较两个String的值是否相等(字符循环对比)
compareTo():比较两个字符串是否相等(字符相减对比)
indexOf():查询字符串首次出现的下标位置
lastIndexOf():查询字符串最后出现下标位置
contains():查询字符串中是否包含另一个字符串
toLowerCase():把字符串全部转化为小写
toUpperCase():把字符串全部转化为大写
length():查询字符串的长度
trim():去掉字符串收尾的空格
replace():资环字符串为某些字符串
split():把字符分割成char数组
join():把字符串数组换换为字符串(可以加分割符)
4、== 和 equals的区别是什么?
== 对于基本类型来说,是用于比较"值"是否相等的,而对于引用类型来说,是用于比较引用地址是否相同的。
equals的源码其实是属于object的,String重写了equals方法,源码如下:
equals在object中的实现:
public boolean equals(Object obj) {
return (this == obj);
}
equals在String中的实现:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
5、String 和StringBuilder StringBuffer有什么区别?
String类型是不可变的,所在字符串拼接的时候如果使用String的话性能会很低,
因此就需要使用另一个数据类型StringBuffuer,
它提供了append和insert方法可以用于字符串的拼接,
它使用synchronize来保证线程安全。
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
@Override
public synchronized StringBuffer insert(int offset, Object obj) {
toStringCache = null;
super.insert(offset, String.valueOf(obj));
return this;
}
所以在性能上不是很高,所以1.5 就有了StringBuilder没有使用synchronize修饰,单线程性能会比较好。
6、String的intern()方法有什么含义?String类型在JVM(java虚拟机)中是如何存储的?编译器对String做了那些优化?
String常见的创建方式有两种:
1、String s1 = “java” 直接赋值的方式
2、String s2 = new String(“java”) 的方式
两者在JVM的存储区域截然不同,jdk s1 常量池(先寻找,如果没有创建再返回常量句柄),s2存堆 s2.intern() 才会存储到常量池。
String s3 = “ja”+“va”
s3 == s1 ture 这是jvm 对String的优化