Java中 new Integer 与 Integer.valueOf 的区别
创始人
2024-05-29 15:50:05
0

引入:new Integer(18) 与 Integer.valueOf(18) 有区别吗?有的话,有什么区别?

我们都知道,使用 new 关键字的时候,每次都会新创建一个对象。但是,Integer.valueOf() 会新创建一个对象吗?

我们来看下面这段代码:

/*** new Integer与 Integer.valueOf() 的区别** @author qiaohaojie* @date 2023/3/4  16:23*/
public class ValueOfMethod {public static void main(String[] args) {Integer x = new Integer(18);Integer y = new Integer(18);System.out.println(x == y); // falseInteger a = Integer.valueOf(18);Integer b = Integer.valueOf(18);System.out.println(a == b); // trueInteger m = Integer.valueOf(300);Integer n = Integer.valueOf(300);System.out.println(m == n); // false}
}

这个结果出现的原因是这样的:

  1. 第一个结果是 false 是因为两次使用 new 时,创建的是两个不同的对象,也就意味着地址不同,所以结果是 false;
  2. 第二个结果是 true 是因为 Integer.valueOf() 方法会使用常量缓存池中的对象,无论调用多少次,都只会取同一个对象的引用;
  3. 第三个结果是 false 是因为 Integer 内置的 256 个缓存数据是在 -128~127 之间,超过这个范围时会创建新的对象。而 300>127 ,所以 m 和 n 会创建两个新的对象,地址也就不同了,所以结果与第一种是一样的 false。

基本数据类型的包装类除了 Float 和 Double之外,其他六个包装类(Byte、Short、Integer、Long、Character、Boolean)都有对应的常量缓存池:

  • Byte:-128~127
  • Short:-128~127
  • Integer:-128~127
  • Long:-128~127
  • Character:\u0000~\u007F
  • Boolean:true、false

接着我们来扒一下 valueOf() 方法的源码:

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

我们可以看到,valueOf() 方法内部主要使用了一个静态内部类 IntegerCache

private static class IntegerCache {static final int low = -128;static final int high;static final Integer cache[];static {// high value may be configured by propertyint 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_VALUEh = 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;}private IntegerCache() {}
}

我们都知道,用 static 关键字外加一个大括号括起来的代码被称为静态代码块,通常用来初始化一些静态变量,优先于 main() 方法执行。

在静态代码块中,low 为 -128,也就是缓存池的最小值;high 默认是 127,也就是缓存才能中的最大值,一共是 256 个。

可以在 JVM 启动的时候,通过 -XX:AutoBoxCacheMax=NNN 来设置缓存池的大小,但是不能无限大,最大到 Integer.MAX_VALUE -129。

然后,开始初始化 cache 数组的大小(256),然后开始从下标为 0 开始遍历填充。

最后一行代码 assert IntegerCache.high >= 127 中,assert 是 Java 中的一个关键字,是断言的意思,只是为了方便调试,并不是指发布程序的组成部分。默认情况下,断言是关闭的,我们可以在命令行运行 Java 程序的时候加上 -ea 参数打开断言。

断言的意思可以当成 if…else 语句来理解:


if(假设成立)
{程序正常运行;
}
else
{报错&&终止程序!(避免由程序运行引起更大的错误)  
}

举个例子:

/*** new Integer与 Integer.valueOf() 的区别** @author qiaohaojie* @date 2023/3/4  16:23*/
public class ValueOfMethod {public static void main(String[] args) {int high = 126;assert high >= 127 ? true : false;System.out.println(false);boolean isRight = 1 > 2;assert isRight : "程序错误";System.out.println("程序正常");}
}

输出:
在这里插入图片描述
缓存池之所以使用 assert 是因为这样做可以提高程序的整体性能。因为相比较而言,比如说 Integer,在 128~127 这个范围内的 256 个数字使用的频率相对会高一些。

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
修复 爱普生 EPSON L4... L4151 L4153 L4156 L4158 L4163 L4165 L4166 L4168 L4...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...