Java面试题之String常见问题

1、创建String的两种方式
String s1 = "abc";
String s2 = new String("abc");
2、String不能被继承,因为String类被final修饰

String的对象一旦被创建,则不能修改,是不可变的,所谓的修改其实是创建了新的对象,所指向的内存空间不变,因为String是不可变类,所以可以安全的用于多线程中。
在这里插入图片描述

3、比较两个字符串的方法

String内部实现了Comparable接口,有两个比较方法:compareTo(String anotherString) 和compareToIgnoreCase(String str)
①、compareTo()方法
与传入的anotherString字符串进行比较,如果小于传入的字符串返回负数,如果大于则返回正数。当两个字符串值相等时,返回0,此时eqauls方法会返回true。
②、compareToIgnoreCase()方法
该方法与compareTo方法类似,区别只是内部利用了toUpperCase等方法进行了大小写转换后进行比较。

4、String、StringBuilder、StringBuffer的区别

①、String是不可变类,每当我们对String进行操作的时候,总是会创建新的字符串。操作String很耗资源,所以Java提供了两个工具类来操作String:StringBuffer和StringBuilder。
②、StringBuffer,也被final修饰,不可被继承,但是它是可变类,绝大多数方法都进行了同步处理。
③、StringBuilder,StringBuilder是JDK1.5发布的,它和StringBuffer本质上没什么区别,就是去掉了保证线程安全的那部分,减少了开销。

5、字符串常量池

例一:

public static void main(String[] args){
        String s1 = "a";
        String s2 = "a";
        System.out.println(s1 == s2); //true,比较地址值,都在常量池,相等
        System.out.println(s1.equals(s2)); //true,equals中,先判断两个对象的地址值,地址值相同,默认就是同一个对象,不会继续equals中的具体值是否相等的判断了,直接会返回true。
    }

例二:

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

例三:

String s1 = "a" + "b" + "c";
String s2 = "abc";
System.out.println(s1 == s2);          //true         地址值相同,都是常量,在常量池里面        
System.out.println(s1.equals(s2));    //true   地址值相同,默认同一个对象,值当然也是相等的。

例四:

String s1 = "ab";
String s2 = "abc";
String s3 = s1 + "c";
System.out.println(s3 == s2);               //false   不相等,s1是变量,编译的时候确定不了值,在内存中会创建值,s3在堆内存中,。s2在常量池,所以不相等。
System.out.println(s3.equals(s2));      //true   比较两个对象的值相等。

例五:

String s1 = "a";
String s2 = "a";
String s3 = "a" + s2;
String s4 = "a" + "a";
String s5 = s1 + s2;
//表达式只有常量时,编译期完成计算
//表达式有变量时,运行期才计算,所以地址不一样
System.out.println(s3 == s4); //false
System.out.println(s3 == s5); //false
System.out.println(s4 == "aa"); //true

例六:

String s3 = new String("xyz");
String s4 = new String("xyz");
System.out.println(s3==s4);

对例六解释如下:
结果是 false

采用new关键字新建一个字符串对象时,JVM首先在字符串池中查找有没有"xyz"这个字符串对象,如果有,则不在池中再去创建"xyz"这个对象了,直接在堆中创建一个"xyz"字符串对象,然后将堆中的这个"xyz"对象的地址返回赋给引用s3,这样,s3就指向了堆中创建的这个"xyz"字符串对象;如果没有,则首先在字符串池中创建一个"xyz"字符串对象,然后再在堆中创建一个"xyz"字符串对象,然后将堆中这个"xyz"字符串对象的地址返回赋给s3引用,这样,s3指向了堆中创建的这个"xyz"字符串对象。s4则指向了堆中创建的另一个"xyz"字符串对象。s3 、s4是两个指向不同对象的引用,结果当然是false。

例七:

String s1 = "abc";
StringBuffer s2 = new StringBuffer(s1);
System.out.println(s1.equals(s2));
//输入false,因为s2不是String类型,String的equals方法进行了类型判断
6、String的intern()方法

当intern()方法被调用,如果字符串池中含有一个字符串和当前调用方法的字符串eqauls相等,那么就会返回池中的字符串。如果池中没有的话,则首先将当前字符串加入到池中,然后返回引用。

String s1 = "abc";
String s2 = new String("abc");
String s3 = s2.intern();
System.out.println(s1 ==s2); // false
System.out.println(s1 == s3); //true
7、字符串创建对象的问题

下面的代码将创建几个字符串对象。

String s1 = new String("Hello");  
String s2 = new String("Hello");

答案是3个对象.
第一,行1 字符串池中的“hello”对象。
第二,行1,在堆内存中带有值“hello”的新字符串。
第三,行2,在堆内存中带有“hello”的新字符串。这里“hello”字符串池中的字符串被重用。

String s = new String("abc");

上述语句可能会创建一个或两个对象,当字符串常量池中已经存在了“abc",则只会创建一个new String对象;如果字符串池中不存在"abc",则会先在字符串池中创建"abc",再在堆中创建new String对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值