热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Boolean、Byte、Short、Integer、Long、Character的缓存机制

2019独角兽企业重金招聘Python工程师标准装箱都是执行valueOf方法:如果有缓存将判定是否在缓存范围内,否则new。拆箱则是执行xxxV

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

装箱都是执行valueOf方法:如果有缓存将判定是否在缓存范围内,否则new。

拆箱则是执行xxxValue方法!

public static boolean isSuspend(Double code) {return code == (int) 1;}public static void main(String[] args) {isSuspend(2d);}

入参先做装箱处理Double.valueOf;再做拆箱处理Double.doubleValue。
说明:拆箱与当前自己的包装类有关!

Java 语言规范中的缓存行为

在 Boxing Conversion 部分的Java语言规范(JLS)规定如下:

详情可见: https://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.1.7 下的 【5.1.7. Boxing Conversion】、【5.1.8. Unboxing Conversion】

if the value p being boxed is an integer literal of type int between -128 and 127 inclusive (§3.10.1), or the boolean literal true or false (§3.10.3), or a character literal between '\u0000' and '\u007f' inclusive (§3.10.4), then let a and b be the results of any two boxing conversions of p. It is always the case that a == b.
如果一个变量 p 的值属于:-128至127之间的整数,true 和 false的布尔值,’u0000′ 至 ‘u007f’ 之间的字符中时,将 p 包装成 a 和 b 两个对象时,可以直接使用 a == b 判断 a 和 b 的值是否相等。

A boxing conversion may result in an OutOfMemoryError if a new instance of one of the wrapper classes (BooleanByteCharacterShortIntegerLongFloat, or Double) needs to be allocated and insufficient storage is available.

5.1.7 章节阐述: 

  1. 当内存空间不足以分配时,出现OutOfMemoryError; 
  2. 对于除 float、double外的的基本数据类型在自动装箱时有缓存Cache; 
  3. 在float、double装箱时,需要关注是否是NaN(Not-a-Number)

5.1.8 章节在关于拆箱的描述中: 如果为null时,将抛出NullPointerException.

Double:/*** A constant holding a Not-a-Number (NaN) value of type* {@code double}. It is equivalent to the value returned by* {@code Double.longBitsToDouble(0x7ff8000000000000L)}.*/public static final double NaN = 0.0d / 0.0;Float:/*** A constant holding a Not-a-Number (NaN) value of type* {@code float}. It is equivalent to the value returned by* {@code Float.intBitsToFloat(0x7fc00000)}.*/public static final float NaN = 0.0f / 0.0f;

eg.

Integer aa = 127, bb = 127;System.out.println(aa == bb); //true aa = 128;bb = 128;System.out.println(aa == bb); //false --因为128超出范围System.out.println(aa.equals(bb)); //true Integer a = 10; //this is autoboxingInteger b = Integer.valueOf(10); //under the hoodSystem.out.println(a == b); // trueFloat c = 0f / 0f;Float d = 0f;System.out.println(c == d); // false -- c是NaNSystem.out.println(c.isNaN()); // trueSystem.out.println(d.isNaN()); // falseDouble e = 0d / 0d;Double f = 0d;System.out.println(e == f); // false -- e是NaNSystem.out.println(e.isNaN()); // trueSystem.out.println(f.isNaN()); // false

Integer

在 Java 5 中,为 Integer 的操作引入了一个新的特性,用来节省内存和提高性能。整型对象在内部实现中通过使用相同的对象引用实现了缓存和重用。上面的规则适用于整数区间 -128 到 +127
这种 Integer 缓存策略仅在自动装箱(autoboxing)的时候有用,使用构造器创建的 Integer 对象不能被缓存。
Java 编译器把原始类型自动转换为封装类的过程称为自动装箱(autoboxing),这相当于调用 valueOf 方法!

Integer a = 10; //this is autoboxing
Integer b = Integer.valueOf(10); //under the hood

源码如下:

在-128到127区间将取缓存中的,超出范围后会new新的地址堆对象。

/*** Returns an {&#64;code Integer} instance representing the specified* {&#64;code int} value. If a new {&#64;code Integer} instance is not* required, this method should generally be used in preference to* the constructor {&#64;link #Integer(int)}, as this method is likely* to yield significantly better space and time performance by* caching frequently requested values.** This method will always cache values in the range -128 to 127,* inclusive, and may cache other values outside of this range.** &#64;param i an {&#64;code int} value.* &#64;return an {&#64;code Integer} instance representing {&#64;code i}.* &#64;since 1.5*/public static Integer valueOf(int i) {if (i >&#61; IntegerCache.low && i <&#61; IntegerCache.high)return IntegerCache.cache[i &#43; (-IntegerCache.low)];return new Integer(i);}

IntegerCache

 Integer 类中一个私有的静态类。

Javadoc 详细的说明这个类是用来实现缓存支持&#xff0c;并支持 -128 到 127 之间的自动装箱过程。最大值 127 可以通过 JVM 的启动参数 -XX:AutoBoxCacheMax&#61;size 修改。 缓存通过一个 for 循环实现。从小到大的创建尽可能多的整数并存储在一个名为 cache 的整数数组中。这个缓存会在 Integer 类第一次被使用的时候被初始化出来。以后&#xff0c;就可以使用缓存中包含的实例对象&#xff0c;而不是创建一个新的实例(在自动装箱的情况下)。

实际上在 Java 5 中引入这个特性的时候&#xff0c;范围是固定的 -128 至 &#43;127。后来在 Java 6 中&#xff0c;最大值映射到 java.lang.Integer.IntegerCache.high&#xff0c;可以使用 JVM 的启动参数设置最大值。这使我们可以根据应用程序的实际情况灵活地调整来提高性能。是什么原因选择这个 -128 到 127 这个范围呢&#xff1f;因为这个范围的整数值是使用最广泛的。 在程序中第一次使用 Integer 的时候也需要一定的额外时间来初始化这个缓存。

/*** Cache to support the object identity semantics of autoboxing for values between* -128 and 127 (inclusive) as required by JLS.** The cache is initialized on first usage. The size of the cache* may be controlled by the {&#64;code -XX:AutoBoxCacheMax&#61;} option.* During VM initialization, java.lang.Integer.IntegerCache.high property* may be set and saved in the private system properties in the* sun.misc.VM class.*/private static class IntegerCache {static final int low &#61; -128;static final int high;static final Integer cache[];static {// high value may be configured by propertyint h &#61; 127;String integerCacheHighPropValue &#61;sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");if (integerCacheHighPropValue !&#61; null) {try {int i &#61; parseInt(integerCacheHighPropValue);i &#61; Math.max(i, 127);// Maximum array size is Integer.MAX_VALUEh &#61; Math.min(i, Integer.MAX_VALUE - (-low) -1);} catch( NumberFormatException nfe) {// If the property cannot be parsed into an int, ignore it.}}high &#61; h;cache &#61; new Integer[(high - low) &#43; 1];int j &#61; low;for(int k &#61; 0; k &#61; 127;}private IntegerCache() {}}

缓存

Byte&#xff0c;Short&#xff0c;Long、Integer的缓存有固定范围: -128 到 127&#xff0c;对于 Character缓存范围是 0 到 127除了 Integer 可以通过参数改变范围外&#xff0c;其它的都不行

tip1: 
    String  valueOf方法只有对boolean的处理返回字面量&#xff08;字符串常量池&#xff09;&#xff0c; 其他都是new新的&#xff01;

    public static String valueOf(boolean b) {
        return b ? "true" : "false";
    }

tip2: 对于Byte而言值的范围在[-128&#xff0c;127] 

byte占一个字节空间&#xff0c;最高位是符号位&#xff0c;剩余7位能表示0-127&#xff0c;加上符号位的正负&#xff0c;就是-127至&#43;127&#xff0c;但负0没必要&#xff0c;为充分利用&#xff0c;就用负零表示-128&#xff08;即原码1000&#xff0c;0000&#xff09;。&#xff08;计算机转补码后存储&#xff09;

对于boolean类型&#xff1a; 提供静态的2中枚举值

public static Boolean valueOf(boolean b) {return (b ? TRUE : FALSE);}

ByteCache 缓存 Byte 、ShortCache 缓存 Short 、 LongCache 缓存 Long <三者源码类似,>

private static class LongCache {private LongCache(){}static final Long cache[] &#61; new Long[-(-128) &#43; 127 &#43; 1];static {for(int i &#61; 0; i

CharacterCache 缓存 Character

private static class CharacterCache {private CharacterCache(){}static final Character cache[] &#61; new Character[127 &#43; 1];static {for (int i &#61; 0; i

测试&#xff1a;

public static void main(String[] args) {Long a &#61; 3L;Integer b &#61; 4;Character c &#61; 5;Byte d &#61; 7;Short e &#61; 1;System.out.println(a &#61;&#61; Long.valueOf(a));System.out.println(b &#61;&#61; Integer.valueOf(b));System.out.println(c &#61;&#61; Character.valueOf(c));System.out.println(d &#61;&#61; Byte.valueOf(d));System.out.println(e &#61;&#61; Short.valueOf(e));}

运行的结果都为true&#xff01;

在断点单测时发现&#xff1a;都跳入了valueOf方法&#xff01;


转:https://my.oschina.net/u/3434392/blog/3009210



推荐阅读
  • 本文介绍如何使用 Python 的 DOM 和 SAX 方法解析 XML 文件,并通过示例展示了如何动态创建数据库表和处理大量数据的实时插入。 ... [详细]
  • 大类|电阻器_使用Requests、Etree、BeautifulSoup、Pandas和Path库进行数据抓取与处理 | 将指定区域内容保存为HTML和Excel格式
    大类|电阻器_使用Requests、Etree、BeautifulSoup、Pandas和Path库进行数据抓取与处理 | 将指定区域内容保存为HTML和Excel格式 ... [详细]
  • 在软件开发过程中,经常需要将多个项目或模块进行集成和调试,尤其是当项目依赖于第三方开源库(如Cordova、CocoaPods)时。本文介绍了如何在Xcode中高效地进行多项目联合调试,分享了一些实用的技巧和最佳实践,帮助开发者解决常见的调试难题,提高开发效率。 ... [详细]
  • 深入解析C语言中结构体的内存对齐机制及其优化方法
    为了提高CPU访问效率,C语言中的结构体成员在内存中遵循特定的对齐规则。本文详细解析了这些对齐机制,并探讨了如何通过合理的布局和编译器选项来优化结构体的内存使用,从而提升程序性能。 ... [详细]
  • Java Socket 关键参数详解与优化建议
    Java Socket 的 API 虽然被广泛使用,但其关键参数的用途却鲜为人知。本文详细解析了 Java Socket 中的重要参数,如 backlog 参数,它用于控制服务器等待连接请求的队列长度。此外,还探讨了其他参数如 SO_TIMEOUT、SO_REUSEADDR 等的配置方法及其对性能的影响,并提供了优化建议,帮助开发者提升网络通信的稳定性和效率。 ... [详细]
  • 在处理 XML 数据时,如果需要解析 `` 标签的内容,可以采用 Pull 解析方法。Pull 解析是一种高效的 XML 解析方式,适用于流式数据处理。具体实现中,可以通过 Java 的 `XmlPullParser` 或其他类似的库来逐步读取和解析 XML 文档中的 `` 元素。这样不仅能够提高解析效率,还能减少内存占用。本文将详细介绍如何使用 Pull 解析方法来提取 `` 标签的内容,并提供一个示例代码,帮助开发者快速解决问题。 ... [详细]
  • 利用ZFS和Gluster实现分布式存储系统的高效迁移与应用
    本文探讨了在Ubuntu 18.04系统中利用ZFS和Gluster文件系统实现分布式存储系统的高效迁移与应用。通过详细的技术分析和实践案例,展示了这两种文件系统在数据迁移、高可用性和性能优化方面的优势,为分布式存储系统的部署和管理提供了宝贵的参考。 ... [详细]
  • 利用python爬取豆瓣电影Top250的相关信息,包括电影详情链接,图片链接,影片中文名,影片外国名,评分,评价数,概况,导演,主演,年份,地区,类别这12项内容,然后将爬取的信息写入Exce ... [详细]
  • 检查在所有可能的“?”替换中,给定的二进制字符串中是否出现子字符串“10”带 1 或 0 ... [详细]
  • PTArchiver工作原理详解与应用分析
    PTArchiver工作原理及其应用分析本文详细解析了PTArchiver的工作机制,探讨了其在数据归档和管理中的应用。PTArchiver通过高效的压缩算法和灵活的存储策略,实现了对大规模数据的高效管理和长期保存。文章还介绍了其在企业级数据备份、历史数据迁移等场景中的实际应用案例,为用户提供了实用的操作建议和技术支持。 ... [详细]
  • Git命令基础应用指南
    本指南详细介绍了Git命令的基础应用,包括如何使用`git clone`从远程服务器克隆仓库(例如:`git clone [url/path/repository]`)以及如何克隆本地仓库(例如:`git clone [local/path/repository]`)。此外,还提供了常见的Git操作技巧,帮助开发者高效管理代码版本。 ... [详细]
  • Android 构建基础流程详解
    Android 构建基础流程详解 ... [详细]
  • 通过优化动态网络Cookies的全网互通机制,实现了用户在任意子站点的登录和注销操作均能同步至整个网络。具体实现涉及对三个关键文件的修改:首先,在`incDv_ClsMain.asp`中定位并调整`Response.Cookies`的相关设置;其次,更新`global.asa`以确保会话状态的一致性;最后,修改`login.asp`以支持跨域认证。这一改进不仅提升了用户体验,还增强了系统的安全性和可靠性。 ... [详细]
  • 利用Anaconda高效管理多版本Python环境
    通过Anaconda,可以高效地管理和切换不同版本的Python环境,为开发人员提供便捷的工具支持。此外,Anaconda还集成了丰富的科学计算和数据分析库,进一步提升了开发效率。对于Golang开发者而言,Anaconda同样是一个值得了解的工具,尽管其主要应用于Python生态。 ... [详细]
  • Python 程序转换为 EXE 文件:详细解析 .py 脚本打包成独立可执行文件的方法与技巧
    在开发了几个简单的爬虫 Python 程序后,我决定将其封装成独立的可执行文件以便于分发和使用。为了实现这一目标,首先需要解决的是如何将 Python 脚本转换为 EXE 文件。在这个过程中,我选择了 Qt 作为 GUI 框架,因为之前对此并不熟悉,希望通过这个项目进一步学习和掌握 Qt 的基本用法。本文将详细介绍从 .py 脚本到 EXE 文件的整个过程,包括所需工具、具体步骤以及常见问题的解决方案。 ... [详细]
author-avatar
xuzhaotong
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有