1.缓冲池

1.1 new Integer(123) 与 Integer.valueOf(123) 的区别在于:

  • new Integer(123) :每次都会新建一个对象
  • Integer.valueOf(123) :会使用缓存池中的对象,多次调用会取得同一个对象的引用。
Integer x = new Integer(123);
Integer y = new Integer(123);
System.out.println(x == y); // false
Integer z = Integer.valueOf(123);
Integer k = Integer.valueOf(123);
System.out.println(z == k); // true

1.2 valueOf() 方法的实现

先判断值是否在缓存池中,如果在的话就直接返回缓存池的内容。

public static Integer valueOf(int i) {if (i >= IntegerCache.low && i <= IntegerCache.high)return IntegerCache.cache[i + (-IntegerCache.low)];return new Integer(i);
}

1.3 在 Java 8 中,Integer 缓存池的大小默认为 -128~127。

1.4 自动装箱

编译器会在自动装箱过程调用 valueOf() 方法,因此多个 Integer 实例使用自动装箱来创建并且值相同,那么就会引用相同的对象。

Integer m = 123;
Integer n = 123;
System.out.println(m == n); // true

1.5 基本类型对应的缓冲池如下:

  • boolean values true and false
  • all byte values
  • short values between -128 and 127
  • int values between -128 and 127
  • char in the range \u0000 to \u007F

在使用这些基本类型对应的包装类型时,就可以直接使用缓冲池中的对象

2. String

2.1 概览

String 被声明为 final,因此它不可被继承

内部使用 char 数组存储数据,该数组被声明为 final,这意味着 value 数组初始化之后就不能再引用其它数组。

并且 String 内部没有改变 value 数组的方法,因此可以保证 String 不可变。

public final class String implements java.io.Serializable, Comparable<String>, CharSequence {/** The value is used for character storage. */private final char value[];...

2.2 不可变的好处

2.2.1 可以缓存 hash 值

因为 String 的 hash 值经常被使用,例如 String 用做 HashMap 的 key。

不可变的特性可以使得 hash 值也不可变,因此只需要进行一次计算

2.2.2 String Pool 的需要

如果一个 String 对象已经被创建过了,那么就会从 String Pool 中取得引用

只有String 是不可变的,才可能使用 String Pool。

2.2.3 安全性

String 经常作为参数,String 不可变性可以保证参数不可变

例如在作为网络连接参数的情况下如果 String 是可变的,那么在网络连接过程中,String 被改变,改String 对象的那一方以为现在连接的是其它主机,而实际情况却不一定是。

2.2.4 线程安全

String 不可变性天生具备线程安全,可以在多个线程中安全地使用。

3. String, StringBuffer and StringBuilder(详细介绍)

3.1. 可变性

  • String 不可变;
  • StringBuffer 和 StringBuilder 可变。

3.2 线程安全

  • String 不可变,因此是线程安全的;
  • StringBuilder 不是线程安全的;
  • StringBuffer 是线程安全的,内部使用 synchronized 进行同步。

3.3 String.intern()

使用 String.intern() 可以保证相同内容的字符串变量引用同一的内存对象

下面示例中,s1 和 s2 采用 new String() 的方式新建了两个不同对象,而 s3 是通过 s1.intern() 方法取得一个对象引用。intern() 首先把 s1 引用的对象放到 String Pool(字符串常量池) 中,然后返回这个对象引用。因此 s3 和 s1 引用的是同一个字符串常量池的对象。

String s1 = new String("aaa");
String s2 = new String("aaa");
System.out.println(s1 == s2); // false
String s3 = s1.intern();
System.out.println(s1.intern() == s3); // true
System.out.println(s1 == s3); // false

如果是采用 "bbb" 这种使用双引号的形式创建字符串实例,会自动地将新建的对象放入 String Pool 中。

String s4 = "bbb";
String s5 = "bbb";
System.out.println(s4 == s5); // true

在 Java 7 之前,字符串常量池被放在运行时常量池中,它属于永久代

而在 Java7,字符串常量池被移到 Native Method 中。这是因为永久代的空间有限,在大量使用字符串的场景下会导致OutOfMemoryError 错误。

缓冲池、String/StringBuffer/StringBuilder、intern()相关推荐

  1. 浅谈 Java 字符串(String, StringBuffer, StringBuilder)

    我们先要记住三者的特征: String 字符串常量 StringBuffer 字符串变量(线程安全) StringBuilder 字符串变量(非线程安全) 一.定义 查看 API 会发现,String ...

  2. String StringBuffer StringBuilder区别与联系

    String     StringBuffer     StringBuilder String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且浪费大量 ...

  3. String StringBuffer StringBuilder的区别

    简单的事情做到极致也是一种能力. 首先,说一下目前我还没进行整理的情况下,我的理解: String 不可修改 修改后相当于又新创建创建一个字符串 比如: String a = "abc&qu ...

  4. String,StringBuffer,StringBuilder三者的异同

    String,StringBuffer,StringBuilder三者的异同:? String:不可变的字符序列;底层使用char[]存储(用final修饰) StringBuffer:可变的字符序列 ...

  5. 重温java中的String,StringBuffer,StringBuilder类

    不论什么一个系统在开发的过程中, 相信都不会缺少对字符串的处理. 在 java 语言中, 用来处理字符串的的类经常使用的有 3 个: String.StringBuffer.StringBuilder ...

  6. String, StringBuffer, StringBuilder之间的区别

    String与StringBuffer/StringBuilder之间的主要区别 1.String对象不可变, 如果修改会重新创建一个对象, 然后把值保存进去. StringBuffer/String ...

  7. java中 String StringBuffer StringBuilder的区别

    * String类是不可变类,只要对String进行修改,都会导致新的对象生成. * StringBuffer和StringBuilder都是可变类,任何对字符串的改变都不会产生新的对象. 在实际使用 ...

  8. String, StringBuffer,StringBuilder

    String, StringBuffer,StringBuilder的区别 java中String.StringBuffer.StringBuilder是编程中经常使用的字符串类,都实现了CharSe ...

  9. `java`学习笔记(十二)`Java`--`String``StringBuffer``StringBuilder`

    Java–String&&StringBuffer&&StringBuilder 文章目录 `Java`--`String`&&`StringBuffe ...

  10. StringBuffer类,StringBuffer类和String的区别、String,StringBuffer,StringBuilder之间的区别

    1.概述 StringBuffer是一个线程安全的可变序列. 2.StringBuffer与String区别 (1)StringBuffer的长度和内容都可以发生改变,String却不行 (2)Str ...

最新文章

  1. 基于Vue和axios的音乐播放器——悦听音乐效果展示及代码分享
  2. Spring 的持久化实例(JDBC, JdbcTemplate、HibernateDaoSupport、JdbcDaoSupport、SqlSessionDaoSupport等)...
  3. 联想揭晓首款基于 Arm 的电脑,未来的发展方向怎样?
  4. 作为一个部门 Leader,居然不如一个实习生
  5. “达观杯”文本智能处理冠军分享:深度学习文本分类
  6. 标准模块 os.path
  7. python机器学习之特征值处理(sklearn)
  8. kali Xss 渗透测试工具
  9. 【C++】字体文件解析(FreeType)
  10. 如何使用SLM生成涡旋光束
  11. 《Git与Github使用笔记》第8章 github常见操作和常见错误
  12. 二项堆(Binomial Heap)
  13. iOS获取路由器地址
  14. OSGB压缩算法有哪些?
  15. 浮点数与32位16进制互转(有代码)
  16. Java枚举—枚举进阶
  17. 确保软件开发生命周期(SDLC)的安全
  18. js取小数点后两位 方法总结
  19. python实现图像白平衡
  20. redis BITFIELD详解

热门文章

  1. 出租司机给我上的MBA课 -- [ 来自: ] [作者:cexo255]
  2. CycleGAN非配对图像生成,定制你的卡通照
  3. Scala模拟Spark分布式计算流程示例代码
  4. 布隆过滤器(Bloom Filter)原理及优缺点剖析
  5. Golang协程goroutine和管道channel结合案例
  6. Docker容器间Link单向通信
  7. JVM调优:定位垃圾的常用算法
  8. Java动态代理代码案例:使用cglib实现对无接口的类进行动态代理
  9. synchronized与java.util.concurrent.locks.Lock的相同之处和不同之处
  10. Linux vim编辑器常用命令