【疑问解决】在自动装箱中Integer赋予一个常量1,为什么会出现==判断true和flase的情况(JDK源码、内部缓冲)

问题来源自讲课时的Integer练习中

当时第一反应是false        true        true

因为第一段的输出为flase毋庸置疑了,因为已经new了两个新的堆空间,当然指向不同的空间了

但是第二段第三段就没有头绪了,自动装箱了难道不是执行同一个空间吗 。

实际上要看自动装箱时的隐式调用Integer.valueOf的源代码

解答:

        输出为false true true

        第一段是对的,但第二端隐式调用了Integer的valueOf方法,使用debug可以追入

1.if语句内的low和high值

        进入该方法后,可以看到有if语句分别判断执行两个return,先看if里面的

if (i >= IntegerCache.low && i <= IntegerCache.high)

        这一句话里面的IntegerCache.low和.high是谁呢?接着追入可以发现

        这个low和high在本类开头已经声明了,而且是静态的,在类加载的时候就已经赋值完毕了,low=-128。

         这段源码重要的是看if语句有没有执行,而在这个if语句块内,执行的是判断有没有在虚拟机初始化时设置初始值,如果没有设置初始值,将默认为空,因为getSavedProperty方法返回java.lang.String为空

String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");

         调用虚拟机的获取设置,编译时不输入就为空

public static java.lang.String getSavedProperty(java.lang.String s) { /* compiled code */ }

         为空不执行if语句high被赋予默认值127,所以min = -128,high = 127

2.if块内return的东西

        到目前为止,我们解决了if判断是从-128 && 127的值(127可以通过jvm设置)

        接下来探讨return后面的一串是什么东西

        首先是cache,我们可以发现格式是一个数组,使用查找可以找到在本来开头定义了一个对象数组

        注意,这里的对象是static的,所以在类加载的时候编创建好了,我们再找找该静态对象在哪里被赋值或者创建

        查找可以发现,cache数组对象在类被调用时创建了个大小为127+128+1大小的数组,通过for循环赋值从j++也就是-128 ++直到255,这时的k循环从0~255,数值大小循环为-128到127。

         随后if语句块内的就很好理解了,cache已经是静态对象而且被创建好了,直接返回对应的数值的数组对象下标回去即可,这一个机制也叫JDK的内部缓冲

        

3.if语句块外的

        这个就没什么好解释的了,在-128到127范围之外的我简单粗暴的new一个int i 的值的对象返回给你就行了

更多关于该JDK内部缓冲的分析请参考

OpenJDK源码研究笔记(五)-缓存Integer等类型的频繁使用的数据和对象,大幅度提升性能(一道经典的Java笔试题)_51CTO博客_openjdk使用

总结

        因为题目的第二段我们赋的值是int常量,使用自动装箱隐式调用valueOf方法,在该方法内if判断为真,返回静态对象cache[129] = Interger(1)回去,所以此时的m指向Interger(1)对象,然后第二句同理,n也指向Interger(1)对象,所以sout(m == n)打印为true

        然后第三段,前面的都同理,但x和y都不在-128~127内在if判断时为假,直接new一个新空间,所以x和y当然执行两个不同的新空间,所以==为false

        所以正确答案为 false true flase,完毕

题目代码

/**
 * @author 银海
 * @version 1.0
 */
public class WrapperExercise02 {
    public static void main(String[] args) {
        Integer i = new Integer(2);
        Integer j = new Integer(1);
        System.out.println(i == j);  //False
        //所以,这里主要是看范围 -128 ~ 127 就是直接返回
        /*
        老韩解读
        //1. 如果i 在 IntegerCache.low(-128)~IntegerCache.high(127),就直接从数组返回
        //2. 如果不在 -128~127,就直接 new Integer(i)
         public static Integer valueOf(int i) {
            if (i >= IntegerCache.low && i <= IntegerCache.high)
                return IntegerCache.cache[i + (-IntegerCache.low)];
            return new Integer(i);
        }
         */
        Integer m = 1; //底层 Integer.valueOf(1); -> 阅读源码
        Integer n = 1;//底层 Integer.valueOf(1);
        System.out.println(m == n); //T
        //所以,这里主要是看范围 -128 ~ 127 就是直接返回
        //,否则,就new Integer(xx);
        Integer x = 128;//底层Integer.valueOf(1);
        Integer y = 128;//底层Integer.valueOf(1);
        System.out.println(x == y);//False

    }
}

JDK源码有关源码

     /**
     * 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 {@code -XX:AutoBoxCacheMax=<size>} 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 = -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++);
    
    /**
     * Returns an {@code Integer} instance representing the specified
     * {@code int} value.  If a new {@code Integer} instance is not
     * required, this method should generally be used in preference to
     * the constructor {@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.
     *
     * @param  i an {@code int} value.
     * @return an {@code Integer} instance representing {@code i}.
     * @since  1.5
     */
    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
    /**
     * The value of the {@code Integer}.
     *
     * @serial
     */
    private final int value;

    /**
     * Constructs a newly allocated {@code Integer} object that
     * represents the specified {@code int} value.
     *
     * @param   value   the value to be represented by the
     *                  {@code Integer} object.
     */
    public Integer(int value) {
        this.value = value;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/106325.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

服务网络基础

服务网络基础 目录 前言 从今天开始我们将进入服务网格的学习&#xff0c;服务网格是微服务架构中的一种重要的技术&#xff0c;它可以解决微服务架构中的一些问题&#xff0c;比如服务发现、服务治理、服务监控等等&#xff0c;我们将从服务网格的基础开始&#xff0c;逐步深…

怎么突破反爬虫机制

在当今的数字化时代&#xff0c;网络爬虫已经成为了收集信息和数据的重要工具。然而&#xff0c;许多网站和平台都配备了反爬虫机制&#xff0c;以防止恶意攻击和过度访问。对于普通用户来说&#xff0c;如何突破这些反爬虫机制呢&#xff1f;本文将为你提供一些实用的技巧和建…

权限系统设计(转载)

1 为什么需要权限管理 2 权限模型 2.1 权限设计 2.2 为什么需要角色 2.3 权限模型的演进 2.4 用户划分 2.5 理想的RBAC模型 3 权限系统表设计 3.1 标准RBAC模型表设计 3.2 理想RBAC模型表设计 4 结语 1 为什么需要权限管理 日常工作中权限的问题时时刻刻伴随着我们&a…

流程引擎-自定义函数的应用

背景&#xff1a; 某些业务需求比较特殊&#xff0c;需要在表单中校验或实现一些功能&#xff0c;泛微流程表单配置时实现的方式多种多样&#xff1a;JS脚本、SQL语句、公式以及其他一些标准化拖拽功能&#xff0c;本次给大家分享一下流程表单中的公式实现的一些需求场景。泛微…

Python轮廓追踪【OpenCV形态学操作】

文章目录 概要代码运行结果 概要 一些理论知识 OpenCV形态学操作理论1 OpenCV形态学操作理论2 OpenCV轮廓操作|轮廓类似详解 代码 代码如下&#xff0c;可以直接运行 import cv2 as cv# 定义结构元素 kernel cv.getStructuringElement(cv.MORPH_RECT, (3, 3)) # print kern…

安装虚拟机找不到虚拟网啦1(eth1)不出现

一、安装虚拟机找不到虚拟网啦1&#xff08;eth1&#xff09;不出现 1、先安装virtualbox 2、再安装vagrant 3、在windows使用ipconfig没有VirtualBoxHost-OnlyNetWork解决方法 1) 解决办法 在windows的设置中找到 网络和Internet 选项&#xff0c;选择右侧 更改适配器选项 …

selenium+python web自动化测试框架项目实战实例教程

自动化测试对程序的回归测试更方便。 由于回归测试的动作和用例是完全设计好的,测试期望的结果也是完全可以预料的,将回归测试自动运行... 可以运行更加繁琐的测试 自动化测试的一个明显好处就是可以在很短的时间内运行更多的测试。学习自动化测试最终目的是应用到实际项目中&…

Android Studio 导出 jar

AS版本&#xff1a;Android Studio Giraffe | 2022.3.1 Patch 1 1、File——New Module——Android Library 2、mylibrary——main——新建功能类 3、mylibrary——build.gradle——android {}内复制以下代码——Sync Now //Copy类型 tasks.register(makeJar, Copy) { //删…

【Java 进阶篇】Java Request 继承体系详解

在Java编程中&#xff0c;Request&#xff08;请求&#xff09;是一个常见的概念&#xff0c;特别是在Web开发中。Request通常用于获取来自客户端的信息&#xff0c;以便服务器能够根据客户端的需求提供相应的响应。在Java中&#xff0c;Request通常涉及到一系列类和接口&#…

CentOS 编译安装TinyXml2

安装 TinyXml2 Git 源码下载地址:https://github.com/leethomason/tinyxml2 步骤1&#xff1a;首先&#xff0c;你需要下载tinyxml2的源代码。你可以从Github或者源代码官方网站下载。并上传至/usr/local/source_code/ 步骤2&#xff1a;下载完成后&#xff0c;需要将源代码解…

Java IDEA feign调用上传文件MultipartFile以及实体对象亲测可行

Java IDEA feign调用上传文件MultipartFile以及实体对象亲测可行 1. 报错 java.lang.IllegalStateException: Body parameter cannot be used with form parameters2. 解决参考 1. 报错 java.lang.IllegalStateException: Body parameter cannot be used with form parameters …

1-多媒体通信概述

文章目录 媒体和多媒体媒体多媒体VarityIntergrationInteraction 多媒体通信(MMC)业务类型 MMC主要问题和关键技术主要问题关键技术 MMC发展动向重要事件趋势 标准化组织 媒体和多媒体 媒体 承载信息的载体. 感知媒体, 表示媒体, 显示媒体, 存储媒体, 传输媒体. 多媒体 Var…

【设计模式】第3节:设计模式概论

设计模式不是代码&#xff0c;而是某类问题的通用方案。设计模式的本质是提高软件的维护性、通用性和扩展性&#xff0c;并降低软件的复杂度。一共有24种设计模式&#xff0c;可以分为创建型模式、结构型模式和行为型模式三大类。设计模式中比较重要的有&#xff1a;单例模式、…

Spring Authorization Server 1.1 扩展实现 OAuth2 密码模式与 Spring Cloud 的整合实战

目录 前言无图无真相创建数据库授权服务器maven 依赖application.yml授权服务器配置AuthorizationServierConfigDefaultSecutiryConfig 密码模式扩展PasswordAuthenticationTokenPasswordAuthenticationConverterPasswordAuthenticationProvider JWT 自定义字段自定义认证响应认…

C++(Qt)软件调试---线程死锁调试(15)

C(Qt)软件调试—线程死锁调试&#xff08;15&#xff09; 文章目录 C(Qt)软件调试---线程死锁调试&#xff08;15&#xff09;1、前言2、常见死锁3、linux下gdb调试C死锁1.1 使用代码1.2 gdb调试 3、linux下gdb调试Qt死锁1.1 使用代码1.2 gdb调试 4、Windows下gdb调试C死锁5、W…

Selenium+Pytest自动化测试框架详解

前言 selenium自动化 pytest测试框架 本章你需要 一定的python基础——至少明白类与对象&#xff0c;封装继承&#xff1b;一定的selenium基础——本篇不讲selenium&#xff0c;不会的可以自己去看selenium中文翻译网 一、测试框架简介 测试框架有什么优点 代码复用率高&…

【LeetCode】5. 最长回文子串

题目链接 文章目录 Python3方法&#xff1a; 暴力求解 ⟮ O ( n 3 ) 、 O ( 1 ) ⟯ \lgroup O(n^3)、O(1)\rgroup ⟮O(n3)、O(1)⟯方法一&#xff1a; 动态规划 (回文串同时去掉头尾后 依然是回文串) ⟮ O ( n 2 ) ⟯ \lgroup O(n^2)\rgroup ⟮O(n2)⟯⭐ 方法二&#xff1a;…

网工内推 | 急招网工,思科、华为认证优先,法定节假日三薪

01 江苏臻云技术 招聘岗位&#xff1a;网络工程师 职责描述&#xff1a; 1、负责落实数据中心机房日常网络监测及巡检任务&#xff1b; 2、负责数据中心网络设备日常监控、变更、维护、巡检&#xff1b; 3、负责日常巡检报告、故障维护报告、变更申请的文档的编制&#xff1b;…

番外8.2 --- 后续

### 01&#xff1a;dd命令&#xff1a;在新挂载点创建swap文件大小10MB&#xff1b;&#xff08;dd if/dev/zero of/swap bs1024 count10240&#xff09; 02&#xff1a;给swap建立文件系统&#xff0c;将其分属到swap文件&#xff08;mkswap /swap&#xff1b; swapon /swap &…

下载视频号安装,下载视频号安装到手机上?

在数字化时代&#xff0c;随着社交媒体的蓬勃发展&#xff0c;视频内容正成为品牌传播和用户吸引的重要方式。而作为当下最热门的短视频平台之一&#xff0c;视频号为用户提供了创作、分享和推广优质内容的机会。如果您还不了解视频号视频或想进一步了解如何下载视频号视频&…