最近在看一些String的面试题,而后就想着把它整顿起来,之后如果还有看到其余的也会持续增加进来

常见问题

1.String中,==和equals()的区别
答:equals实质上是==,然而String重写了equals办法,在String中,==比拟的是两个对象的援用地址是否相等,而equals比拟的是两个字符串对象的字面量是否相等。
2.两个对象的hashCode雷同,equals肯定雷同吗?
答:不是,两个对象的hash雷同,equals不肯定雷同,然而equals雷同,hashCode肯定雷同
3.创立String对象有几种形式

    String a = "";    String b = new String();    String c = String.class.newInstance();    clone的形式    反序列化的形式

4.在Java中,创建对象有几种形式

1)new一个 对象2)通过构造方法3)利用反射创立一个对象--String.class.newInstance()4)利用Object的clone办法5)反序列化形式

5.以下代码创立出几个对象?---4个

        String a = "abc";        String b = new String("abc");        String c = "abc";        String d = new String("xyz");

6.以下代码创立出几个对象?
答:依据不同的编译器有不同的状况

  • 有的java编译器是创立3个对象,"abc"一个,"xyz"一个,两者相加当前又造成一个对象"abcxyz"
  • 官网的编译器,只会创立出1个,在编译阶段它将"abc"和"xyz"拼接在一起造成一个对象"abcxyz",对象a存着该"abcxyz"的援用地址
   String a = "abc" + "xyz" 

7.以下代码会创立几个对象?
答:0个,只会有一个新的索引a,空串在Java虚拟机启动的时候默认生成的

     String a = "";

8.以下代码会创立几个对象?
答:4个,首先"abc"对象在常量池里被创立,而后在堆内存里创立了对象b,之后"xyz"对象在常量池被创立,而后用+=进行拼接的时候,b被结构成StringBuilder对象,调用append拼接了"xyz",之后原本应该是要调用toString()办法转换成String对象,然而+=把这一步给省略了

    String b = new String("abc");    b += "xyz";

9.以下的第三行代码创立出几个对象(第一和第二行不算入)

        String var1 = "abc";        String var2 = new String("abc");        String str = var1 + var2;

答:两个对象,一个是String对象,另一个是StringBuilder对象,当咱们没有应用str变量时,底层会创立一个StringBuilder对象,调用append办法把var1和var2拼接起来,最初调用toString()办法返回。
而当咱们应用str变量时,产生出一个String对象,编译器会做一个优化。底层是通过var1+var2办法拼接字符串,比方如下.class代码:

    应用str:    public static void main(String[] args) {        String var1 = "abc";        String var2 = new String("abc");        String str = var1 + var2;        System.out.println(str);    }        不应用str: public static void main(String[] args) {        String var1 = "abc";        String var2 = new String("abc");        (new StringBuilder()).append(var1).append(var2).toString();    }

10.new String("abc")底层的创立过程?
答:首先,先在常量池外面创立一个"abc"字符串对象,这个对象指向了一个char数组['a','b','c'],而后在堆内存里开拓一块空间创立了String对象,这个字符串对象也指向了这个char数组

11.String字符串的hash值什么时候被赋值
答:默认hash值为0,当调用带String参数的构造方法时会被初始化为传入的那个字符串参数的hash,还有就是当调用字符串的hashCode办法时hash值会被计算出来

12.以下代码打印进去的后果是什么
答:是abc,应用带char数组参数的构造方法,底层是把char数组的内容复制一份给了字符串,所以chars数组和str底层的value数组不是同一个数组,即便扭转了chars数组的内容,str还是不变。

        char[] chars = {'a','b','c'};        String str = new String(chars);        chars[0] = 'x';        System.out.println(str);

13.以下三种创立String对象的形式有什么区别吗?

    String str1 = new String();    String str2 = new String("");    String str3 = "";

答:str1和str2都是在堆内存里创立了一个对象,并指向了""字符串的援用地址,然而str2在结构的时候并把""字符串的hash值赋给了str2,所以相比于str1来说,在之后的操作中,就不必再去计算hash值,性能会进步。而str3相比于前两种,它只是在栈内存里开拓了一个空间指向了常量区里的""字符串对象

14.以下代码中,str2和str3哪种创立形式更好?

    String str1 = "abc";    String str2 = new String("abc");    String str3 = new String(str1);

答:str2和str3两个对象都是指向常量区外面同一个"abc"字符串对象的value数组,所以从运行层面上来看两种办法都是一样的。
但在编译的时候,如果间接用字符串常量的形式结构,编译器会去遍历常量区里的所有字符串,直到找到"abc"字符串,再去结构str2。而str3在结构的时候,因为str1指向的是一个援用地址,相当于间接通知str3你要的字符串常量就在我保留的这个地位,这样就省去了遍历常量区的过程,速度会更快一点。

15.为什么在循环的时候,String用+号进行字符串拼接效率低?
答:因为应用+进行拼接的话,编译器每一次的拼接都会创立一个StringBuilder对象将每个+号前面的字符串通过append办法拼接起来,然而每循环一次都会产生一个StringBuilder对象,当循环的次数很大的时候,效率天然就升高了