Marvel-Site Marvel-Site
首页
  • Java

    • Java基础
    • Java进阶
    • Java容器
    • Java并发编程
    • Java虚拟机
  • 计算机基础

    • 数据结构与算法
    • 计算机网络
    • 操作系统
    • Linux
  • 框架|中间件

    • Spring
    • MySQL
    • Redis
    • MQ
    • Zookeeper
    • Git
  • 架构

    • 分布式
    • 高并发
    • 高可用
    • 架构
  • 框架

    • React
    • 其他
  • 实用工具
  • 安装配置

    • Linux
    • Windows
    • Mac
  • 开发工具

    • IDEA
    • VsCode
  • 关于
  • 收藏
  • 草稿
  • 索引

    • 分类
    • 标签
    • 归档
GitHub (opens new window)

Marvel

吾必当乘此羽葆盖车
首页
  • Java

    • Java基础
    • Java进阶
    • Java容器
    • Java并发编程
    • Java虚拟机
  • 计算机基础

    • 数据结构与算法
    • 计算机网络
    • 操作系统
    • Linux
  • 框架|中间件

    • Spring
    • MySQL
    • Redis
    • MQ
    • Zookeeper
    • Git
  • 架构

    • 分布式
    • 高并发
    • 高可用
    • 架构
  • 框架

    • React
    • 其他
  • 实用工具
  • 安装配置

    • Linux
    • Windows
    • Mac
  • 开发工具

    • IDEA
    • VsCode
  • 关于
  • 收藏
  • 草稿
  • 索引

    • 分类
    • 标签
    • 归档
GitHub (opens new window)
  • Java

    • Java基础

    • Java进阶

      • 类的初始化与对象的初始化
      • Object类
      • 深度理解字符串String
      • Integer创建对象分析
        • 1 测试
        • 2 解释
          • int i = 1
          • Integer i = new Integer(1)
          • Integer.valueOf(1)
          • Integer.valueOf(1111)
      • 从原理上分析 i = i++ 与 i = ++i
      • Comparable和Comparator的区别
      • 四种引用介绍
      • 静态代理与动态代理
      • 位运算
    • Java容器

    • Java并发编程

    • Java虚拟机

    • 常见面试题

  • 计算机基础

  • 框架|中间件

  • 架构

  • 后端
  • Java
  • Java进阶
Marvel
2022-07-14
目录

Integer创建对象分析

# Integer创建对象分析

# 1 测试

先看看下面的测试:

⭐ 测试1

@Test
public void test1() {
    Integer i1 = 1;
    Integer i2 = 1;
    System.out.println(i1 == i2);  // true

    Integer i3 = new Integer(1);
    Integer i4 = new Integer(1);
    System.out.println(i3 == i4);  // false
	
	Integer i5 = Integer.valueOf(1);
    Integer i6 = Integer.valueOf(1);
    System.out.println(i5 == i6);  // true
    
    Integer i9 = Integer.valueOf(1111);
    Integer i10 = Integer.valueOf(1111);
    System.out.println(i9 == i10);  // false
    
    Integer i11 = 1111;
    Integer i12 = 1111;
    System.out.println(i11 == i12);  // false
    
    int i7 = 1;
    int i8 = 1;
    System.out.println(i7 == i8);  // true
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

⭐ 测试2

@Test
public void test2() {
    int i1 = 1;
    Integer i2 = 1;
    Integer i3 = new Integer(1);
    Integer i4 = Integer.valueOf(1);

    System.out.println(i1 == i2);  // true
    System.out.println(i1 == i3);  // true
    System.out.println(i1 == i4);  // true
    System.out.println(i2 == i3);  // false
    System.out.println(i2 == i4);  // true
    System.out.println(i3 == i4);  // false
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 2 解释

# int i = 1

@Test
public void test4() {
    int i1 = 1;
    int i2 = 1;
    int i3 = 1;

    System.out.println(i1 == i2);  // true
    System.out.println(i1 == i3);  // true
    System.out.println(i2 == i3);  // true
}
1
2
3
4
5
6
7
8
9
10

在内存中是这样的

在这里插入图片描述

# Integer i = new Integer(1)

Integer i = new Integer(1) 每次都会新建一个对象。

@Test
public void test3() {
    Integer i1 = new Integer(1);
    Integer i2 = new Integer(1);
    Integer i3 = new Integer(1);

    System.out.println(i1 == i2);  // false
    System.out.println(i1 == i3);  // false
    System.out.println(i2 == i3);  // false
}
1
2
3
4
5
6
7
8
9
10

内存中是这样,i1 i2 i3是3个不同的对象。

在这里插入图片描述

# Integer.valueOf(1)

Integer.valueOf(1) 会使用缓存池中的对象,多次调用会取得同一个对象的引用。

@Test
public void test5() {
    Integer i1 = Integer.valueOf(1);
    Integer i2 = Integer.valueOf(1);
    Integer i3 = Integer.valueOf(1);

    System.out.println(i1 == i2);  // true
    System.out.println(i1 == i3);  // true
    System.out.println(i2 == i3);  // true
}
1
2
3
4
5
6
7
8
9
10

内存中是这样,i1 i2 i3是3个相同的对象。

在这里插入图片描述

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
2
3
4
5

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

static final int low = -128;
static final int high;
static final Integer cache[];

static {
    // high value may be configured by property
    int h = 127;
    String integerCacheHighPropValue =
        sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
    if (integerCacheHighPropValue != null) {
        try {
            int i = parseInt(integerCacheHighPropValue);
            i = Math.max(i, 127);
            // Maximum array size is Integer.MAX_VALUE
            h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
        } catch( NumberFormatException nfe) {
            // If the property cannot be parsed into an int, ignore it.
        }
    }
    high = h;

    cache = new Integer[(high - low) + 1];
    int j = low;
    for(int k = 0; k < cache.length; k++)
        cache[k] = new Integer(j++);

    // range [-128, 127] must be interned (JLS7 5.1.7)
    assert IntegerCache.high >= 127;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

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

Integer m = 1;
Integer n = 1;
System.out.println(m == n); // true
1
2
3

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

  • 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

在使用这些基本类型对应的包装类型时,如果该数值范围在缓冲池范围内,就可以直接使用缓冲池中的对象。

在 jdk 1.8 所有的数值类缓冲池中,Integer 的缓冲池 IntegerCache 很特殊,这个缓冲池的下界是 - 128,上界默认是 127,但是这个上界是可调的,在启动 jvm 的时候,通过-XX:AutoBoxCacheMax=<size>来指定这个缓冲池的大小,该选项在 JVM 初始化的时候会设定一个名为java.lang.IntegerCache.high系统属性,然后 IntegerCache 初始化的时候就会读取该系统属性来决定上界。

# Integer.valueOf(1111)

上面介绍了valueOf的缓存值范围为-128~127,而1111超出了这个范围,所以Integer i1 = Integer.valueOf(1111)等价于Integer i1 = new Integer(1111)。

@Test
public void test6() {
    Integer i1 = Integer.valueOf(1111);
    Integer i2 = Integer.valueOf(1111);
    Integer i3 = Integer.valueOf(1111);

    System.out.println(i1 == i2);  // false
    System.out.println(i1 == i3);  // false
    System.out.println(i2 == i3);  // false
}
1
2
3
4
5
6
7
8
9
10

内存中是这样,i1 i2 i3是3个不同的对象。

编辑 (opens new window)
#Java
上次更新: 2023/08/20, 21:21:52
深度理解字符串String
从原理上分析 i = i++ 与 i = ++i

← 深度理解字符串String 从原理上分析 i = i++ 与 i = ++i→

最近更新
01
位运算
05-21
02
二叉树
05-12
03
Spring三级缓存解决循环依赖
03-25
更多文章>
Theme by Vdoing | Copyright © 2022-2024 Marvel
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式