面试 Java 基础八股文十问十答第十五期

作者:程序员小白条,个人博客

相信看了本文后,对你的面试是有一定帮助的!关注专栏后就能收到持续更新!

⭐点赞⭐收藏⭐不迷路!⭐

1)为什么 String 是不可变的?

String 是不可变的主要有以下几个原因:

  • 安全性: 不可变性可以确保字符串的内容在创建后不能被修改。这对于一些安全性敏感的操作(例如密码、网络连接等)是很重要的,因为字符串不可变性可以防止在使用过程中的意外修改。
  • 线程安全性: 不可变性使得字符串在多线程环境下更容易管理。多个线程可以同时访问一个字符串对象,而无需担心对象被修改。
  • 缓存哈希值: 不可变字符串的哈希值在创建时可以进行缓存,因为它们永远不会改变。这在需要频繁计算哈希值的场景中提供了性能优势。
  • 字符串池: 由于字符串是不可变的,可以被存储在字符串池中,以便在程序中共享。这可以减少内存占用,提高性能。
2)String 真的是不可变的吗?

尽管 String 被设计为不可变的,但通过反射机制和一些特殊处理,可以在运行时进行修改。这不是一个推荐的做法,因为它违背了字符串不可变性的设计原则,并可能导致不可预测的行为。

3)是否可以继承 String 类?

在 Java 中,String 类是 final 类,因此不能被继承。final 关键字表示该类不能被其他类继承。这是为了确保字符串的不可变性和安全性。如果 String 类可以被继承,那么子类可能会修改字符串的内容,从而破坏了字符串的不可变性。如果需要扩展字符串的功能,可以使用其他相关的类,比如 StringBuilderStringBuffer,它们提供了可变的字符串操作。

4)数组有没有 length() 方法?

在 Java 中,数组是一种特殊的对象,它具有一个名为 length 的属性,用于获取数组的长度。注意,length 是一个属性而不是方法,因此不需要使用括号来调用。

int[] arr = {1, 2, 3, 4, 5};int length = arr.length;System.out.println("数组的长度为:" + length);
5)String 有没有 length() 方法?

是的,String 类有一个名为 length() 的方法,用于获取字符串的长度,即字符串中字符的数量。

String str = "Hello, World!";int length = str.length();System.out.println("字符串的长度为:" + length);
6)String 类的常用方法都有哪些?

String 类提供了许多常用的方法来操作字符串,其中一些包括:

  • length():返回字符串的长度(字符的数量)。
  • charAt(int index):返回指定索引位置的字符。
  • substring(int beginIndex):返回从指定索引开始到字符串末尾的子字符串。
  • substring(int beginIndex, int endIndex):返回从指定开始索引到结束索引之间的子字符串。
  • indexOf(String str):返回指定子字符串在当前字符串中第一次出现的位置索引。
  • indexOf(String str, int fromIndex):返回指定子字符串从指定位置开始在当前字符串中第一次出现的位置索引。
  • lastIndexOf(String str):返回指定子字符串在当前字符串中最后一次出现的位置索引。
  • lastIndexOf(String str, int fromIndex):返回指定子字符串从指定位置开始在当前字符串中最后一次出现的位置索引。
  • startsWith(String prefix):检查字符串是否以指定的前缀开头。
  • endsWith(String suffix):检查字符串是否以指定的后缀结尾。
  • toLowerCase():将字符串中的所有字符转换为小写。
  • toUpperCase():将字符串中的所有字符转换为大写。
  • trim():去除字符串两端的空白字符。
  • replace(char oldChar, char newChar):将字符串中所有的旧字符替换为新字符。

这些只是 String 类中的一部分常用方法,还有许多其他方法可以用于字符串操作。

7)在使用 HashMap 的时候,用 String 做 key 有什么好处?

使用 String 作为 HashMap 的 key 有以下好处:

  • 不可变性保证安全性: String 是不可变的,因此它的哈希值在创建时就确定,并且在整个生命周期内不会发生变化。这确保了在 HashMap 中使用 String 作为 key 时的稳定性和安全性,避免了哈希值变化导致的不一致性。
  • 哈希值的缓存: String 类在创建时会计算并缓存其哈希值,因为它是不可变的,所以这个缓存的哈希值是安全的。在 HashMap 中使用 String 作为 key 可以直接利用这个缓存的哈希值,提高了获取 key 的哈希值的性能。
  • 易于读取: 作为字符串,HashMap 中使用的 String key 可以直观地表示,易于理解和调试。

综上所述,使用 String 作为 HashMap 的 key 可以确保稳定性、安全性,并提高性能。

8)String 和 StringBuffer、StringBuilder 的区别是什么?String 为什么是不可变的?

  • String: String 类是不可变的,意味着一旦创建就不能被修改。每次对 String 进行操作时,都会创建一个新的字符串对象,原对象不会被修改。String 的不可变性主要基于以下原因:
    • 安全性:不可变性可以确保字符串的内容在创建后不能被修改,这对于安全性敏感的操作是很重要的。
    • 线程安全性:不可变性使得字符串在多线程环境下更容易管理。
    • 缓存哈希值:不可变字符串的哈希值在创建时可以进行缓存,提高了性能。
  • StringBuffer 和 StringBuilder: StringBuffer 和 StringBuilder 类是可变的,它们支持对字符串进行动态修改。主要区别在于线程安全性,StringBuffer 是线程安全的,而 StringBuilder 不是。这是因为 StringBuffer 的方法使用了 synchronized 关键字进行同步,而 StringBuilder 没有。

综上所述,String 是不可变的主要基于安全性、线程安全性和性能等考虑。

9)拆箱:将包装类型转换为基本数据类型; int 和 Integer 有什么区别?

在 Java 中,int 是基本数据类型,而 Integer 是 int 的包装类型。它们之间的区别主要有以下几点:

  • 数据类型: int 是 Java 的基本数据类型,而 Integer 是 int 的包装类,是一个对象。
  • 默认值: int 的默认值是 0,而 Integer 的默认值是 null(如果未初始化)。
  • 对象和性能: Integer 是一个对象,拆箱操作将 Integer 对象转换为 int 值,这可能会带来性能损失。而直接使用 int 不涉及对象操作,性能更高。
  • 使用场景: 一般情况下,如果只需要操作数值,可以直接使用 int,而如果需要在集合类中操作数值或者需要将数值作为对象处理(比如作为方法参数),则可以使用 Integer。

10)Integer a = 127 和 Integer b = 127 相等吗?

在 Java 中,对于 Integer 类型的对象,如果值在 -128 到 127 之间,会被 JVM 缓存起来,因此相同数值的 Integer 对象引用会指向相同的对象。因此,Integer a = 127Integer b = 127 是相等的,它们引用的是同一个对象。

Integer a = 127;Integer b = 127;System.out.println(a == b);// 输出 true

但是需要注意,如果超出了缓存范围,比如 Integer a = 128Integer b = 128,则会创建新的对象,它们引用的不是同一个对象。

Integer a = 128;Integer b = 128;System.out.println(a == b);// 输出 false

开源项目地址:https://gitee.com/falle22222n-leaves/vue_-book-manage-system

前后端总计已经 700+ Star,1W+ 访问!

⭐点赞⭐收藏⭐不迷路!⭐