美文网首页
Java-面试--String、StringBulider、St

Java-面试--String、StringBulider、St

作者: 李小李的路 | 来源:发表于2019-05-20 17:12 被阅读0次

从元素特性讲

  • String类是final类,也即意味着String类不能被继承,并且它的成员方法都默认为final方法。
  • String类其实是通过char数组来保存字符串的;
  • 对String对象的任何改变都不影响到原对象,相关的任何change操作都会生成新的对象 。

从线程安全讲

  • StringBuffer对象的内容可以修改;而String对象一旦产生后就不可以被修改,重新赋值其实是两个对象。
  • StringBuilder:线程非安全的
  • StringBuffer:线程安全的
    • 为什么线程安全:因为StringBuffer使用了synchronized

适用场景

  • String:适用于少量的字符串操作的情况
  • StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
  • StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

网上流传的面试题

要知道答案,更要知道为什么会有这个答案,后者比前者更重要

1. 下面这段代码的输出结果是什么?

String a = "hello2";   String b = "hello" + 2;   System.out.println((a == b));

输出结果为:true。原因很简单,"hello"+2在编译期间就已经被优化成"hello2",因此在运行期间,变量a和变量b指向的是同一个对象。

2.下面这段代码的输出结果是什么?

String a = "hello2";   String b = "hello"; String c = b + 2; System.out.println((a == c));

输出结果为:false。由于有符号引用的存在,所以 String c = b + 2;不会在编译期间被优化,不会把b+2当做字面常量来处理的,因此这种方式生成的对象事实上是保存在堆上的。因此a和c指向的并不是同一个对象。javap -c得到的内容:

3.下面这段代码的输出结果是什么?

String a = "hello2";   final String b = "hello"; String c = b + 2; System.out.println((a == c));

输出结果为:true。对于被final修饰的变量,会在class文件常量池中保存一个副本,也就是说不会通过连接而进行访问,对final变量的访问在编译期间都会直接被替代为真实的值。那么String c = b + 2;在编译期间就会被优化成:String c = "hello" + 2;

4.下面这段代码输出结果为:

public class Main {
    public static void main(String[] args) {
        String a = "hello2";
        final String b = getHello();
        String c = b + 2;
        System.out.println((a == c));
    }
     
    public static String getHello() {
        return "hello";
    }
}

输出结果为false。这里面虽然将b用final修饰了,但是由于其赋值是通过方法调用返回的,那么它的值只能在运行期间确定,因此a和c指向的不是同一个对象。

5.下面这段代码的输出结果是什么?

public class Main {
    public static void main(String[] args) {
        String a = "hello";
        String b =  new String("hello");
        String c =  new String("hello");
        String d = b.intern();
         
        System.out.println(a==b);
        System.out.println(b==c);
        System.out.println(b==d);
        System.out.println(a==d);
    }
}

答案:false / false / false / true

这里面涉及到的是String.intern方法的使用。在String类中,intern方法是一个本地方法,在JAVA SE6之前,intern方法会在运行时常量池中查找是否存在内容相同的字符串,如果存在则返回指向该字符串的引用,如果不存在,则会将该字符串入池,并返回一个指向该字符串的引用。因此,a和d指向的是同一个对象。

6.String str = new String("abc")创建了多少个对象?

new只调用了一次,也就是说只创建了一个对象。

这个问题如果换成 String str = new String("abc")涉及到几个String对象?合理的解释是2个。

个人觉得在面试的时候如果遇到这个问题,可以向面试官询问清楚”是这段代码执行过程中创建了多少个对象还是涉及到多少个对象“再根据具体的来进行回答。

7.下面这段代码1)和2)的区别是什么?

public class Main {
    public static void main(String[] args) {
        String str1 = "I";
        //str1 += "love"+"java";        1)
        str1 = str1+"love"+"java";      //2)
         
    }
}

1)的效率比 2)的效率要高,1)中的"love"+"java"在编译期间会被优化成"lovejava",而2)中的不会被优化。

注释:在1)中只进行了一次append操作,而在2)中进行了两次append操作。

8.判断定义为String类型的s1和s2是否相等

 String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2);   //true              
System.out.println(s1.equals(s2));    //true

简单的说创建s1的时候会在常量池中创建一个"abc",这个"abc"有一个地址值,然后s1把引用指向"abc"的地址值;创建s2的时候会在常量池中去检查是否有"abc",如果有就直接把引用指向"abc"的地址值,所以s1和s2的地址值相等.

9.判断定义为String类型的s1和s2是否相等

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

这个题和上面的题很像,创建的两个对象一个引用指向的是堆内存,另一个地址是指向常量池.

10.判断定义为String类型的s1和s2是否相等

    * String s1 = "a" + "b" + "c";
    * String s2 = "abc";
    * System.out.println(s1 == s2); //true  
    * System.out.println(s1.equals(s2));    //true

这个题是考的jvm的对String类的常量优化机制,String s1 = "a" + "b" + "c";代码在编译的时候就会生成String s1 = "abc";在创建s2的时候常量池中已经有"abc"了,会直接把引用指向"abc",所以s1和s2的地址值是一样的.

11.判断定义为String类型的s1和s2是否相等

    * String s1 = "ab";
    * String s2 = "abc";
    * String s3 = s1 + "c";
    * System.out.println(s3 == s2);     //false
    * System.out.println(s3.equals(s2));    //true

String类的api这样说的:
Java 语言提供对字符串串联符号("+")以及将其他对象转换为字符串的特殊支持。字符串串联是通过 StringBuilder(或 StringBuffer)类及其 append 方法实现的。字符串转换是通过 toString 方法实现的,该方法由 Object 类定义,并可被 Java 中的所有类继承。

12.面试题:StringBuffer 和数组的区别?

答:二者都可以看出是一个容器,装其他的数据。但是呢,StringBuffer的数据最终是一个字符串数据,而数组可以放置任意类型的同一种数据。

相关文章

网友评论

      本文标题:Java-面试--String、StringBulider、St

      本文链接:https://www.haomeiwen.com/subject/qmzkzqtx.html