java128陷阱

java128陷阱public static void main(String[] args){ Integer a=128; Integer b=128; System.out.print(a==b);//false a=127; b=127; System.out.print(a==b);//true}为什么对于一个Integer来说,两个Integer都为128的时候通过判断为false,127时的却是true呢?其实这一切都是因为Java中的装箱

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

public static void main(String[] args){ 
   
 
    Integer a=128;    
    Integer b=128;
 
    System.out.print(a==b);//false
    a=127;
    b=127;
    System.out.print(a==b);//true
}

为什么对于一个Integer来说,两个Integer都为128的时候通过判断为false,127时的却是true呢?

其实这一切都是因为Java中的装箱和拆箱机制,每一个基本类型都对应有自己的类,如int和Integer,double和Double等.在Integer类中有个valueOf(int i)方法,拆箱就是通过Integer的这个静态方法执行的一系列操作.
在这里插入图片描述

在这个方法中涉及到了IntegerCache这个类中类,在这个类中声明了low和high这两个静态常量,其中low是-128,high没有设置默认值.
在这里插入图片描述

看见low和high再结合128陷阱对int的范围,就能想到了,这个low和high就是控制范围的,那么high会在哪初始化呢?

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++);
 
            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }
 
        private IntegerCache() { 
   }
    }

在加载IntegerCache类的时候执行了该类中的所有static字段,其中在static块中声明并且初始化了h变量为127(???127不就是拆箱的最大值吗),为什么还要多次一举呢?其实在这里有个非常牛批的设定,那就是程序员可以自己设定这个high的大小.

在JVM的设置项中添加以下的句子.

-Djava.lang.Integer.IntegerCache.high=250;

所以说设置之后,变量i读取后值为250大于127,但是又小于Integer.MAX_VALUE – (-low) -1,所以high设置成功,从现在开始所有的-127~250的Integer都不是对象,而是存储在常量池cache中,即IntegerCache.cache,从源码中我们也可以看到cache的大小为(high-low)+1.

好,现在我们就把Integer的问题说清楚了,但是这么做有什么实际意义呢?

其实就是省去了建立过多的对象,比如在淘宝中,127以下的商品有很多,假如把他们都存成Integer对象的话就会占用过多的内存,此时把低于127的存储在数组中就可以省去很多的内存开销.
在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/168706.html原文链接:https://javaforall.net

(0)
上一篇 2022年8月8日 下午4:36
下一篇 2022年8月8日 下午4:36


相关推荐

  • options请求方式

    options请求方式OPTIONS 请求即预检请求 可用于检测服务器允许的 http 方法 当发起跨域请求时 由于安全原因 触发一定条件时浏览器会在正式请求之前自动先发起 OPTIONS 请求 即 CORS 预检请求 服务器若接受该跨域请求 浏览器才继续发起正式请求

    2026年3月18日
    2
  • 汇编学习 NO6

    汇编学习 NO61 ret 用栈中的数据 修改 IP 内容 从而实现近转移 2 retf 用栈中的数据 修改 CS 和 IP 中的内容 从而实现远转移 3 CPU 执行 ret 指令相当于 popIP 执行 retf 指令相当于 popIPpopCS4 call 指令 CPU 执行 call 指令时 进行两步操作 将当前的 IP 或 CS 和 IP 压入栈中 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp

    2026年2月3日
    4
  • js的数据类型有哪些?[通俗易懂]

    js的数据类型有哪些?[通俗易懂]数据类型一、数据类型:基本数据类型(值类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)。引用数据类型(对象类型):对象(Object)、数组(Array)、函数(Function)。特殊的对象:正则(RegExp)和日期(Date)。特殊类型:underfined未定义、Null空对象、Infinate无穷、NAN非数字基本数据类型的值直接在栈内存中存储,值与值之间独立存在,修改一个变量不会影响.

    2025年9月19日
    6
  • 设置CListCtrl单元格的颜色

    设置CListCtrl单元格的颜色pragmaonce//CListCtrlClclassCListCtrlCl:publicCListCtrl{DECLARE_DYNAMIC(CListCtrlCl)public:CListCtrlCl();virtual~CListCtrlCl();protected:DECLARE_MESSAGE_MAP()virtualvo

    2022年6月23日
    29
  • python连接数据库插入数据「建议收藏」

    python连接数据库插入数据「建议收藏」python连接数据库插入数据在数据库创建表并插入测试数据dropdatabaseifexistshrs;createdatabasehrsdefaultcharsetutf8mb4;usehrs;createtabletb_dept(dnointnotnullcomment’编号’,dnamevarchar(10)notnullcomment’名称’,dlocvarchar(20)notnullcomment’所在地’,prim

    2025年7月12日
    4
  • linux shell脚本编写实例_常用的shell脚本

    linux shell脚本编写实例_常用的shell脚本LINUXShell脚本编程实例详解(一)上ping命令测试网段内主机的2例详解使用linux已经有10来年了但是一直止于各种服务器的搭建和环境的调优,能力不能得到提升,今天突然下定决心学习Shell脚本编程,因此以网上广为流传的《Shell脚本100例》为基础学习、实验和笔记。废话不说上栗子。使用vimshell100-scanip-1.sh命令创建脚本文件#!/bin…

    2022年10月3日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号