[关闭]
@lzb1096101803 2016-02-03T14:46:17.000000Z 字数 3286 阅读 468

12. String面试题

面试 Java


  1. String和StringBuffer的区别
    它们可以储存和操作字符串,即包含多个字符的字符数据。String类是不可变的,提供了数值不可改变的字符串。而这个StringBuffer类提供的字符串进行修改。当你知道字符数据要改变的时候你就可以使用StringBuffer。典型地,你可以使用StringBuffer来动态构造字符数据。
    另外,String实现了equals方法,new String(“abc”).equals(new String(“abc”)的结果为true,而StringBuffer没有实现equals方法,所以,new StringBuffer(“abc”).equals(new StringBuffer(“abc”)的结果为false。
    对于String的连接可以查看class文件的反编译后的java文件就知道效率问题

  2. String s = new String("xyz");
    创建了几个String Object?二者之间有什么区别?
    两个或一个,”xyz”对应一个对象,这个对象放在字符串常量缓冲区,常量”xyz”不管出现多少遍,都是缓冲区中的那一个。New String每写一遍,就在堆上创建一个新的对象,它一句那个常量”xyz”对象的内容来创建出一个新String对象。如果以前就用过’xyz’,这句代表就不会创建”xyz”自己了,直接从缓冲区拿。
    class wenjian keyi kandao

  3. StringBuffer与StringBuilder的区别
    StringBuffer和StringBuilder类都表示内容可以被修改的字符串,
    StringBuilder是线程不安全的,运行效率高,
    如果一个字符串变量是在方法里面定义,这种情况只可能有一个线程访问它,不存在不安全的因素了,则用StringBuilder。
    如果要在类里面定义成员变量,并且这个类的实例对象会在多线程环境下使用,那么最好用StringBuffer。

  4. Java的String,StringBuffer,StringBuilder有什么区别?
    那就是:String是不可变类(immutable),每次在String对象上的操作都会生成一个新的对象;StringBuffer和StringBuilder则允许在原来对象上进行操作,而不用每次增加对象;StringBuffer是线程安全的,但效率较低,而StringBuilder则效率最高。
    这个答案我是很早都知道的,而且实际应用中也是这样做的,经常变化的时候用StringBuilder或者StringBuffer
    String和StringBuffer,StringBuilder都是用字符数组来表示的。但是在String中这个字符数组是这样定义的:
    /** The value is used for character storage. /
    private final char value[];
    而在StringBuffer和StringBuilder中,这个字符数组都是继承于java.lang.AbstractStringBuilder中的
    /*

    • The value is used for character storage.
      */
      char value[];
      这样答案就很明显了,原因就在这个final关键字上。
      而同时通过源代码可以发现StringBuffer的很多方法和属性都有synchronized关键字修饰,而StringBuilder则没有。

//1  true
//当两个字符串字面值连接时(相加),得到的新字符串依然是字符串字面值,保存在常量池中
public static void main(String[] args) {   
    String a = "a1";   
    String b = "a" + 1;   
    System.out.println(a == b);   
}  

//2 false
//当字符串字面值与String类型变量连接时,得到的新字符串不再保存在常量池中,而是在堆中新建一个String对象来存放。很明显常量池中要求的存放的是常量,有String类型变量当然不能存在常量池中了
public static void main(String[] args) {   
        String a = "ab";   
        String bb = "b";   
        String b = "a" + bb;   
        System.out.println(a == b);   
}  
//3 true 此处是字符串字面值与String类型常量连接,得到的新字符串依然保存在常量池中。
public static void main(String[] args) {   
    String a = "ab";   
    final String bb = "b";   
    String b = "a" + bb;   
    System.out.println(a == b);   
}

//4 false
//final String bb = getBB();其实与final String bb = new String(“b”);是一样的
//可见并非定义为final的就保存在常量池中,很明显此处bb常量引用的String对象保存在堆中
public static void main(String[] args) {   
        String a = "ab";   
        final String bb = getBB();   
        String b = "a" + bb;   
        System.out.println(a == b);   
}   

private static String getBB() {   
        return "b";   
}  


//5 false true
//当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(用 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并返回此 String 对象的引用。
//它遵循以下规则:对于任意两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。
private static String a = "ab";   

public static void main(String[] args) {   
    String s1 = "a";   
    String s2 = "b";   
    String s = s1 + s2;   
    System.out.println(s == a);   
    System.out.println(s.intern() == a);   
}  


//6 false,false,true
private static String a = new String("ab");   

public static void main(String[] args) {   
        String s1 = "a";   
        String s2 = "b";   
        String s = s1 + s2;   
        System.out.println(s == a);   
        System.out.println(s.intern() == a);   
        System.out.println(s.intern() == a.intern());   
}  

String s = new String("abc");
String s1 = "abc";
String s2 = new String("abc");
System.out.println(s == s1);//false
System.out.println(s == s2);//false
System.out.println(s1 == s2);//false

String s = new String("abc");
String s1 = "abc";
String s2 = new String("abc");
System.out.println(s == s1.intern()); //false
System.out.println(s == s2.intern());//false
System.out.println(s1 == s2.intern());//true

String hello = "hello";
String hel = "hel";
String lo = "lo";
System.out.println(hello == "hel" + "lo");//true
System.out.println(hello == "hel" + lo);//false
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注