Java类型系列--基本数据类型

其他网址

JAVA中Long与Integer比较容易犯的错误(比较数据equals)_java_我主要负责转载优秀的技术博文-CSDN博客

另见:《Java开发实战经典》=> 6.12 包装类

简介

问题起源:Long或Integer如何比较大小呢?

  • 错误方法:
    直接使用==来比较。 因为Long与Ineger都是包装类型,是对象。  而不是普通类型long与int
    使用equals方法。因为equals方法只能比较同类型的类,例如两个都要是Integer类型。
  • 正确方法:用,或者先使用longValue()或intValue()方法来得到他们的基本类型的值然后使用==比较也是可以的。

拆箱与装箱原理

 装箱就是将基本数据类型转化为包装类型,那么拆箱就是将包装类型转化为基本数据类型。

package org.example.a;

public class Demo{
    public static void main(String[] args) {
        //自动装箱,底层其实执行了Integer a=Integer.valueOf(1);
        Integer a = 10;
        //自动拆箱,底层其实执行了int b=a.intValue();
        int b = a;
    }
}

查看反汇编文件

依次执行如下命令

javac -d . org\example\a\Demo.java

javap -c org.example.a.Demo

输出结果如下:

E:\work\idea_proj\test_java\src>javap -c org.example.a.Demo
Compiled from "Demo.java"
public class org.example.a.Demo {
  public org.example.a.Demo();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: bipush        10
       2: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       5: astore_1
       6: aload_1
       7: invokevirtual #3                  // Method java/lang/Integer.intValue:()I
      10: istore_2
      11: return
}

Integer a = 10; 
执行上面那句代码的时候,系统为我们执行了:Integer a = Integer.valueOf(10);

int b = a; 
执行上面那句代码的时候,系统为我们执行了:int b = a.intValue();

缓存问题

分析过程

其他网址

【JAVA】谈谈拆箱与装箱_java_阳阳的博客-CSDN博客

测试代码

package org.example.a;

public class Demo{
    public static void main(String[] args) {
        Integer a = 100;
        Integer b = 100;
        Integer c = 200;
        Integer d = 200;
        System.out.println(a == b);
        System.out.println(c == d);
    }
}

执行结果

true
false

 原因:

Integer有个缓存,原理如下。

 valueOf源码

    //private static class IntegerCache {
    //    static final int low = -128;
    //    static final int high = 127;
    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

        当i的值位于[-128,127]的时候,会直接返回Integer缓存数组中相应对象的引用,如果i大于127或小于-128,会重新创建一个Integer实例,并返回。

        那么第一条式子a和b的值都在缓存范围内,因此他们指向同一个对象,因此返回true。c和d的值不在范围内,都是通过new创建出来的,因此不是同一个对象,返回false。

其他包装类的缓存

        Byte、Short、Integer、Long、Character的valueOf()实现机制类似。

包装类 说明
Byte 相同值的Byte比较永远返回true。因为byte取值范围就是[-128,127]。
Short、Integer、Long 相同值在[-128,127]则返回true,不在则返回false
Character 要返回true,只需保证i <= 127。因为char最小值为0,本来就大于等于-128。
Float、Double 永远返回false。因为其永远返回新创建的对象,因为一个范围内的整数是有限的,但是小数却是无限的,无法保存在缓存中。
Boolean 只有两个对象,要么是true的Boolean,要么是false的Boolean,只要boolean的值相同,Boolean就相等。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章