JAVA BGW笔记
本文最后更新于7 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

为什么String不可变

  • final类:String类被final修饰,意味着它不能被继承
  • private访问权限:存储字符的value数组是private的,外部代码无法直接访问到这个数组。
  • final数组引用:value引用被final修饰,意味着这个引用一旦被赋值,就不能再指向另一个数组

注意:final修饰的是引用,而不是数组本身。可以通过某种方式拿到数据,并且可以修改元素。

主要有以下几点原因:

1.线程安全。不可变对象天生就是线程安全的。因为它们的状态不可变,所以可以被多个线程共享而无需任何同步机制。这极大地提升了性能并降低了复杂性。

2.作为哈希表的键。

  • String 是 HashMapHashSet 等集合最常用的键。
  • 对象的 hashCode() 方法在 String 中是这样计算的:它遍历 value 数组中的字符来计算哈希值。由于字符串不可变,所以哈希值在创建时计算一次并缓存下来(见源码中的 private int hash 字段),之后每次调用 hashCode() 都直接返回缓存值,效率极高。
  • 如果 String 可变,那么修改字符串会导致其哈希值改变,这在 HashMap 中会造成灾难性后果(对象再也找不到了)。

3.出于安全考虑。网络地址URL、文件路径path、密码通常情况下都是以String类型保存,假若String不是固定不变的,将会引起各种安全隐患。比如将密码用String的类型保存,那么它将一直留在内存中,知道垃圾收集把它清除。假如String类不是固定不变的,那么这个密码可能会被改变,导致出现安全隐患。

4.字符串常量池优化。String对象创建之后,会缓存到字符串常量池中,下次需要创建同样的对象时,可以直接返回缓存的引用。

String、StringBuffer和StringBuilder区别

1.可变性

  • String不可变
  • StringBuffer和StringBuilder可变

2.线程安全

  • String不可变,因此是线程安全的
  • StringBudiler不是线程安全的
  • StringBuffer是线程安全的,内部使用synchronied进行同步

总结与使用建议

  • 操作少量的数据字符串内容不常改变:使用String。
  • 在单线程环境下操作大量字符串数据(如在循环中拼接):使用StringBuilder。
  • 在多线程环境下操作大量字符串数据:使用StringBuffer。

一个简单的性能比较:StringBuilder>StringBuffer>String(在频繁修改的场景下)

String类的常用方法有哪些?

  • indexOf():返回指定字符的索引
  • charAt():返回指定索引处的字符
  • replace():字符串替换
  • trim():去除字符串两端空白
  • split():分割字符串,返回一个分割后的字符串数组
  • getBytes():返回字符串的byte类型数组
  • length():返回字符串长度
  • toLowerCase():将字符串转成小写字符
  • toUpperCase():将字符串转成大写字符
  • substring:截取字符串
  • equals():字符串比较

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇