关于基础类型判断相等的原理介绍

1. 前言

我写这篇文章的目的是什么呢?

不在于给出例子的结果,即‘判断基础类型包装类是否相等的结果’。

基于这些问题和结果,我会结合代码原理、栈原理等,讲述结果背后的原理。

java有几种基础数据类型呢?干java这行的,大部分人都知道是8种。

jdk中对它们分别提供了包装类。以下比较相等问题,仅针对包装类进行讨论。

2. 给出问题 

基于下面的代码,读者可以先给出自己的结果。 

    public static void main(String[] args) {
        Integer i =-128;
        Integer j = -128;
        System.out.println(i == j);
        i =127;
        j = 127;
        System.out.println(i == j);
        i =128;
        j = 128;
        System.out.println(i == j);

        test(1);
        test(128);
    }

    public static void test(int i){
        System.out.println("================================");
        Integer i1 = new Integer(i);
        Integer i2 = new Integer(i);
        System.out.println("i1 == i2 : " + (i1 == i2));
        System.out.println("i1.equals(i2) : " + (i1.equals(i2)));

        System.out.println("new Integer(i) == new Integer(i) : " + (new Integer(i) == new Integer(i)));

        System.out.println("Integer.valueOf(i) == Integer.valueOf(i) : " + (Integer.valueOf(i) == Integer.valueOf(i)));

        Integer i3 = Integer.valueOf(i);
        Integer i4 = Integer.valueOf(i);
        System.out.println("i3 == i4 : " + (i3 == i4));
    }

3. 讲述原理 

3.1. new关键字

简述为:触发类加载,为类实例分配内存空间,给出内存空间地址。

3.2. 包装类

3.2.1. 提供包装类型的原因

  • 便于String与基础类型之间互相转换
  • 提供其他有用处的方法

3.2.2. cache部分实例

总述

  • 出于时间和空间考虑,部分包装类会缓存一部分数据,但是缓存只是很小一部分数据,一旦超出范围就用new喽。

cache部分数据的原因

  • 节省空间和时间

cache使用场景

  • 自动装箱时,无须重复new 对象
  • 用于valueof

    如果你还没有看过valueOf源码的话,可以看看下边的注释。

    /**
     * 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);
    }

哪些包装类

  • Byte
  • Short
  • Character
  • Integer
  • Long

cache数据范围

部分包装类缓存的对象数量

Byte 

256(-128 -- 127)

Character

128(0 -- 127)

Short 

256(-128 -- 127)

Integer 

默认256(-128 -- 127)

Long 

256(-128 -- 127)

超过范围怎么办

  • new新对象

3.3. 栈帧的内容

请查看另一篇讲述java内存模型的文章  你可以了解到jvm执行指令时是如何获取数据的。

3.3.1. ==比较什么 

在栈帧部分,已经知道本地变量数组和操作数栈了。那么==的处理过程就是操作数栈弹出的两个数据进行比较。例如引用的实例内存空间地址。

3.3.2. equals做了什么

不考虑float double,其他6中包装类型的equals方法内部均是比较其对应基础类型的数据。

    public int compareTo(Byte anotherByte) {
        return compare(this.value, anotherByte.value);
    }
    public boolean equals(Object obj) {
        if (obj instanceof Byte) {
            return value == ((Byte)obj).byteValue();
        }
        return false;
    }

4. 输出结果

true
true
false
================================
i1 == i2 : false
i1.equals(i2) : true
new Integer(i) == new Integer(i) : false
Integer.valueOf(i) == Integer.valueOf(i) : true
i3 == i4 : true
================================
i1 == i2 : false
i1.equals(i2) : true
new Integer(i) == new Integer(i) : false
Integer.valueOf(i) == Integer.valueOf(i) : false
i3 == i4 : false

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值