java 面试题(总结中)
- 1.为什么String类会设计为final修饰
- 2. 外界初始化内部类对象
- 3.java中的字符串常量池,JVM的什么地方?
1.为什么String类会设计为final修饰
1.为了实现字符串池
保证String不可变,因为只有当字符串是不可变的,字符串池才有可能实现。字符串池的实现可以在运行时节约很多heap空间,因为不同的字符串变量都指向池中的同一个字符串。但如果字符串是可变的,那么String interning将不能实现,因为这样的话,如果变量改变了它的值,那么其它指向这个值的变量的值也会一起改变。
String就被设计成一个不变类,这样有助于共享,提高性能。可以将字符串对象保存在字符串常量池中以供与字面值相同字符串对象共 享。如果String对象是可变的,那就不能这样共享,因为一旦对某一个String类型变量引用的对象值改变,将同时改变一起共享字符串对象的其他 String类型变量所引用的对象的值
2.为了线程安全
3.为了实现String可以创建HashCode不可变性
2. 外界初始化内部类对象
如果在外界初始化内部类对象
class TestInnerClass{
class Inner01{
void say(){
System.out.println("说");
}
}
static clsss Inner02{
}
}
Inner01 t1 = new TestInnerClass().new Inner01();
t1.say();
如果是静态内部类,可以使用下面方式创建
Inner02 t2 = new TestInnerClass.Inner02();
3.java中的字符串常量池,JVM的什么地方?
JDK7之前,类似于字符串常量池等等常量数据都是存储方法区(Method Area),也被叫做永久代
JDK7开始去永久代,将字符串常量池等等常量数据存储到堆内里。
JDK8,元数据区(Metaspace),将1.6其他一些存储在方法区的数据,挪到了元数据区中,
字符串常量池并没有被挪回去
言外之意:java从jdk7,字符串常量池存储在heap中,jdk之前是存储在永久代中。
public class Test{
public static void main(String[] args){
String str ="abc";
String str1 = new String("abc");
String str2 = "abc";
System.out.println(str == str1); //false
System.out.println(str == str2); //true
}
}
注意: 在编译时,已经确定的结果的字符串,不会创建对象,直接比较常量池中的值
在编译的时候,结果不确定,则会创建字符串对象