大家好,我是菜菜,一个为 coding 而生,为 debug 奋斗一辈子的地地道道的码农。
日拱一卒系列,旨在通过对 Java 后端常见的面试题进行剖析,知其然知其所以然,少走弯路,伺机而动。
作为 Java 程序员,项目研发中 String 的 API 可谓是经常使用了,但是下面菜菜遇到的 String 的这些问题,你是否都能答上来呢?
面试官问:String 是否可以继承?
菜菜回答:我看过 String 的源码,String 类用 final 关键字修饰,用 final 修饰的类是不能够被子类继承的。另外 String 类用 final 修饰线程安全,支持字符串常量池共享,在一定程度上会节省资源,提升效率。
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
// ... ...
}
菜菜实验:
Cannot inherit from final 'java.lang.String'
面试官问:String 类常用的方法有哪些?
菜菜回答:
- 在项目开发中,经常会用到 String 的 equals 方法来比较两个字符串的值是否相等;会用 substring 方法进行截取子串;当然会用到 length 方法判断字符串的长度;会用到 split 方法进行拆分字符串;会用到 equalsIngoreCase 方法进行忽略大小写进行比较两个字符串的值是否相等等。
- 在项目开发中经常对 String 这些常用的方法进行封装成工具类,例如 Apache 的 common-lang 包中的 StringUtils、Google Guava 提供的 Strings 等。
菜菜整理:方法用时方恨少,凭感觉罗列一下,未罗列的未必不重要,在某种场景的下,找到最适合的方法进行解决实际问题才最重要。
面试官问:String 是基本数据类型吗?
菜菜回答:String 底层是用 char 数组实现的,String 是引用类型。
面试官问:String 如何转基本类型?基本类型如何变成 String?
菜菜回答:
- String 转成基本类型,可以通过调用基本类型对应包装类提供的 parseXxx 方法来实现字符串转成基本类型,例如 int 对应包装类 Integer 提供的 parseInt 方法。
- String 转成基本类型,还可以通过调用基本类型对应包装类提供的 valueOf 方法来实现字符串转成基本类型,例如 Integer 提供的 valueOf 方法。
- 基本类型转成 String,可以通过基本数据类型与空字符串(“”)进行拼接(+);另一种方式是调用 String 类提供的 valueOf 方法返回相应的字符串。
- 在项目开发中,针对 String 转基本类型推荐使用 valueOf() 方法,而非直接 new 的方式,因为前者效率高一些,具体原因可阅读编码时坏习惯的系列文章,例如《(一)改掉这些坏习惯,还怕写不出健壮的代码? 》。
菜菜源码:
// 问题一:String 如何转基本类型?借助基本类型的包装类提供的方法实现。
public final class Integer extends Number implements Comparable<Integer> {
// ... ...
public static int parseInt(String s) throws NumberFormatException {
return parseInt(s,10);
}
public static Integer valueOf(String s) throws NumberFormatException {
return Integer.valueOf(parseInt(s, 10));
}
// ... ...
}
// 问题二:基本类型如何转 String? 借助 String 提供的 valueOf 方法实现方式。
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
// ... ...
public static String valueOf(int i) {
return Integer.toString(i);
}
public static String valueOf(long l) {
return Long.toString(l);
}
// ... ...
}
面试官问:String s = new String("一猿小讲");创建了几个字符串对象?
菜菜回答:
- 两个。一个是静态区的“一猿小讲”,一个是用 new 在堆上创建的对象。
- 在项目开发中,很少那么干,因为内存开销大而且效率低,建议直接声明初始化 String s = "一猿小讲" 就可以啦。
面试官问:String s = "一猿"; s = s + "小讲";原始的字符串对象中内容有没有改变?
菜菜回答:
- 没有。因为 String 被设计成不可变的类,所以它的所有对象都是不可变对象。在这段代码中,首先 s 指向了一个 String 对象,内容为“一猿”,然后进行字符串 + 操作,这时 s 不再指向原来的 String 对象,而是指向了另一个 String 对象,内容为“一猿小讲”,而原来的那个对象还存在于内存里,只是 s 的引用变量不再指向它了而已。
- 在项目开发中面对字符串值拼接较多的场景,例如老项目中拼接 SQL 的场景,不要求线程安全情况下则推荐使用 StringBuilder,要保证线程安全情况下则推荐使用 StringBuffer。
日拱一卒,一起聊技术、谈业务、喷架构,少走弯路,不踩大坑。会持续输出精彩分享,敬请期待!
历史推文: