优秀的编程知识分享平台

网站首页 > 技术文章 正文

日拱一卒:String 的这些问题,你能说清楚吗?

nanyue 2024-08-01 22:47:52 技术文章 10 ℃

大家好,我是菜菜,一个为 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 类常用的方法有哪些?

菜菜回答:

  1. 在项目开发中,经常会用到 String 的 equals 方法来比较两个字符串的值是否相等;会用 substring 方法进行截取子串;当然会用到 length 方法判断字符串的长度;会用到 split 方法进行拆分字符串;会用到 equalsIngoreCase 方法进行忽略大小写进行比较两个字符串的值是否相等等。
  2. 在项目开发中经常对 String 这些常用的方法进行封装成工具类,例如 Apache 的 common-lang 包中的 StringUtils、Google Guava 提供的 Strings 等。

菜菜整理:方法用时方恨少,凭感觉罗列一下,未罗列的未必不重要,在某种场景的下,找到最适合的方法进行解决实际问题才最重要。

面试官问:String 是基本数据类型吗?

菜菜回答:String 底层是用 char 数组实现的,String 是引用类型。

面试官问:String 如何转基本类型?基本类型如何变成 String?

菜菜回答:

  1. String 转成基本类型,可以通过调用基本类型对应包装类提供的 parseXxx 方法来实现字符串转成基本类型,例如 int 对应包装类 Integer 提供的 parseInt 方法。
  2. String 转成基本类型,还可以通过调用基本类型对应包装类提供的 valueOf 方法来实现字符串转成基本类型,例如 Integer 提供的 valueOf 方法。
  3. 基本类型转成 String,可以通过基本数据类型与空字符串(“”)进行拼接(+);另一种方式是调用 String 类提供的 valueOf 方法返回相应的字符串。
  4. 在项目开发中,针对 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("一猿小讲");创建了几个字符串对象?

菜菜回答:

  1. 两个。一个是静态区的“一猿小讲”,一个是用 new 在堆上创建的对象。
  2. 在项目开发中,很少那么干,因为内存开销大而且效率低,建议直接声明初始化 String s = "一猿小讲" 就可以啦。

面试官问:String s = "一猿"; s = s + "小讲";原始的字符串对象中内容有没有改变?

菜菜回答:

  1. 没有。因为 String 被设计成不可变的类,所以它的所有对象都是不可变对象。在这段代码中,首先 s 指向了一个 String 对象,内容为“一猿”,然后进行字符串 + 操作,这时 s 不再指向原来的 String 对象,而是指向了另一个 String 对象,内容为“一猿小讲”,而原来的那个对象还存在于内存里,只是 s 的引用变量不再指向它了而已。
  2. 在项目开发中面对字符串值拼接较多的场景,例如老项目中拼接 SQL 的场景,不要求线程安全情况下则推荐使用 StringBuilder,要保证线程安全情况下则推荐使用 StringBuffer。

日拱一卒,一起聊技术、谈业务、喷架构,少走弯路,不踩大坑。会持续输出精彩分享,敬请期待!

历史推文:

fastjson的这些坑,你误入了没?

这些技术轮子,让监控落地成为现实

(一)改掉这些坏习惯,还怕写不出健壮的代码?

(二)改掉这些坏习惯,还怕写不出优雅的代码?

(三)改掉这些坏习惯,还怕写不出优雅的代码?

(四)改掉这些坏习惯,还怕写不出健壮的代码?

(五)改掉这些坏习惯,还怕写不出精简的代码?

(六)改掉这些坏习惯,还怕写不出精简的代码?

Tags:

最近发表
标签列表