128陷阱源码级分析

ops/2024/10/11 4:06:45/
一、引言

在Java编程中,128陷阱是一个与==操作符和equals()方法有关的常见问题,特别是在比较Integer对象时。这个陷阱涉及到Java的自动装箱(Autoboxing)和整数缓存机制(Integer Cache)。本文将详细分析128陷阱的源码,并解释其形成原因。

二、128陷阱示例

首先,我们来看一个简单的示例代码:

public static void main(String[] args) {  Integer a = 128;  Integer b = 128;  Integer e = 127;  Integer f = 127;  System.out.println(a == b); // 输出false  System.out.println(a.equals(b)); // 输出true  System.out.println(e == f); // 输出true  System.out.println(e.equals(f)); // 输出true  
}

在上述代码中,a == b的结果为false,而e == f的结果为true,这看起来有些反直觉。接下来,我们将从源码角度分析这一现象。

三、源码分析

128陷阱是Java开发中容易遇到的一个问题,特别是在处理Integer对象的比较时。理解整数缓存机制和正确使用equals()方法是避免这个陷阱的关键。在编写代码时,应尽量避免使用==操作符来比较对象,而是使用equals()方法来确保比较的准确性。

通过本文的源码分析,相信读者对128陷阱的形成原因有了更深入的理解。在实际开发中,应时刻注意这一点,以避免潜在的问题。

  1. 自动装箱

    Java 5引入了自动装箱和拆箱机制,允许将基本数据类型自动转换为对应的包装类对象,反之亦然。例如,Integer a = 128;实际上会调用Integer.valueOf(128)方法。

  2. Integer.valueOf()方法

    Integer.valueOf(int i)方法的源码如下:

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

    该方法首先检查传入的整数i是否在IntegerCache的缓存范围内(默认是-128到127)。如果是,则直接从缓存中返回对应的Integer对象;如果不是,则创建一个新的Integer对象并返回。

  3. IntegerCache类

    IntegerCacheInteger类的一个静态内部类,用于实现整数缓存机制。其源码如下(部分):

    java">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);  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;  }  
    }

        从源码中可以看出,IntegerCache类定义了一个缓存数组cache,用于存储-128到127(包含-128和127)之间的Integer对象。当调用Integer.valueOf(int i)方法时,如果i在缓存范围内,则直接从缓存中返回对应的对象;否则,创建一个新的对象。

四、128陷阱形成原因
  1. 缓存机制

    对于值在-128到127范围内的Integer对象,Java会使用缓存池中的实例。这意味着相同值的Integer对象在该范围内将引用相同的实例。因此,e == f的结果为true

  2. 非缓存机制

    对于超出-128到127范围的值,Integer对象不会被缓存,每次都会创建新的对象。因此,即使两个Integer对象的值相同,它们也不会是同一个实例。所以,a == b的结果为false

  3. ==equals()的区别

    在Java中,==操作符用于比较两个对象的引用是否相同(即是否指向同一个内存地址),而equals()方法用于比较两个对象的值是否相等。因此,当比较两个Integer对象时,应使用equals()方法而不是==操作符来避免128陷阱。

五、总结

128陷阱是Java开发中容易遇到的一个问题,特别是在处理Integer对象的比较时。理解整数缓存机制和正确使用equals()方法是避免这个陷阱的关键。在编写代码时,应尽量避免使用==操作符来比较对象,而是使用equals()方法来确保比较的准确性。

通过本文的源码分析,相信读者对128陷阱的形成原因有了更深入的理解。在实际开发中,应时刻注意这一点,以避免潜在的问题。


http://www.ppmy.cn/ops/123800.html

相关文章

yolov5-7.0模型DNN加载函数及参数详解(重要)

yolov5-7.0模型DNN加载函数及参数详解&#xff08;重要&#xff09; 引言yolov5&#xff08;v7.0&#xff09;1&#xff0c;yolov5.h(加载对应模型里面的相关参数要更改)2&#xff0c;main主程序&#xff08;1&#xff09;加载网络&#xff08;2&#xff09;检测推理&#xff0…

路径跟踪之导航向量场——二维导航向量场

今天带来一期轨迹跟踪算法的讲解&#xff0c;首先讲解二维平面中的导航向量场[1]。该方法具有轻量化、计算简便、收敛性强等多项优点。该方法根据期望的轨迹函数&#xff0c;计算全局位置的期望飞行向量&#xff0c;将期望飞行向量转为偏光角&#xff0c;输入底层控制器&#x…

【网络安全 | Java代码审计】华夏ERP(jshERP)v2.3

未经许可,不得转载。 文章目录 技术框架开发环境代码审计权限校验绕过SQL注入Fastjson反序列化命令执行存储型XSS越权/未授权重置密码越权/未授权删除用户信息越权/未授权修改用户信息会话固定安全建议项目地址:https://github.com/jishenghua/jshERP 技术框架 核心框架:Sp…

JMeter直连数据库

1.在jmeter的lib文件夹下加入jdbc的驱动&#xff1a; 2.新建线程 数据库表t_user&#xff1a; 3.新建察看结果树&#xff1a; 最终查到结果&#xff0c;说明连接成功&#xff01;&#xff01;&#xff01;

后端开发——规则引擎简介(Drools)

目录 什么是规则引擎&#xff1f;规则引擎带来的好处;Drools案例规则引擎的工作原理及应用场景常见的规则引擎及对比工作流引擎与规则引擎有什么不同 什么是规则引擎&#xff1f; 规则引擎&#xff0c;听起来高大上&#xff0c;其实可以理解为一种帮助你做“决策”的工具。你可…

Leetcode—148. 排序链表【中等】

2024每日刷题&#xff08;171&#xff09; Leetcode—148. 排序链表 C实现代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr…

怎么快速申请CNAS认证

要快速申请CNAS&#xff08;中国合格评定国家认可委员会&#xff09;认证&#xff0c;可以按照以下步骤进行&#xff1a; 一、了解CNAS认证要求和流程 查阅CNAS官网&#xff1a;访问CNAS官方网站&#xff0c;了解CNAS认证的基本条件、申请流程、所需材料等信息。 研究认可规则…

C语言-输入输出

实验一&#xff1a;编写一个输出两行自定义字符的 C 程序 一、实验目的 熟悉 C 语言的基本结构和语法。掌握 printf() 函数的使用方法。了解在 Code::Blocks 中编写、编译和运行程序的过程。 二、实验内容 编写一个 C 程序&#xff0c;要求输出两行字符&#xff0c;内容自定…