HelloCoder HelloCoder
首页
《Java小白求职之路》
《小白学Java》
计算机毕设
  • 一些免费计算机资源
  • 脚手架工具
  • 《从0到1学习Java多线程》
  • 《从0到1搭建服务器》
随笔
关于作者
首页
《Java小白求职之路》
《小白学Java》
计算机毕设
  • 一些免费计算机资源
  • 脚手架工具
  • 《从0到1学习Java多线程》
  • 《从0到1搭建服务器》
随笔
关于作者
  • 《PureJavaCoderRoad》

    • 导读

    • Java基础

    • Java进阶

      • 常用类

        • BigDecimal
        • File类
        • Java常用类
        • Math类
        • String
        • StringBuilder、StringBuffer、StringJoiner
        • 包装类型
        • 日期类
      • 集合

      • 反射

      • IO

      • Java新特性

      • 序列化与反序列
      • 泛型
    • Java高阶

    • 开发辅助工具

    • 计算机网络

    • 数据库

    • JavaEE

    • 中间件

    • 架构

    • 建议

  • PureJavaCoderRoad
  • Java进阶
  • 常用类
#包装类型
码农阿雨
2022-05-26
目录

包装类型

此前提到,Java的数据类型分两种:

  • 基本数据类型
  • 引用数据类型

基本数据类型是有默认值的,引用数据类型可以赋值为null,但不是基本数据类型不行。

一个int整数的时候,如果不初始化,默认就是0,但是如何把int整数数据初始化为null,而不是 0 呢?

这时候就需要用到包装类型了 。

Java核心库为每种基本类型都提供了对应的包装类型:

基本类型 对应的引用类型
boolean java.lang.Boolean
byte java.lang.Byte
short java.lang.Short
int java.lang.Integer
long java.lang.Long
float java.lang.Float
double java.lang.Double
char java.lang.Character

基本数据类型和包装数据类型可以相互转换(null 拆箱会报NullPointerException)。

# 1、Integer 与 int

Integer 是 int 整型的包装数据类型。

Integer 比较特别,下面重点来讲讲。

我们定义一个整型的数据可以这样写:

int i =1;
Integer i = 1; 
Integer i = new Integer(1);

但其背后原理是不一样的。

基本数据类型 "==" 比较的是值。

引用数据类型 "==" 比较的是地址。

# 1.1、拆箱与装箱

装箱就是自动将基本数据类型转换为包装器类型;使用Integer.valueOf方法。 拆箱就是自动将包装器类型转换为基本数据类型;使用Integer.intValue方法。

eg:

//自动装箱
Integer total = 99;
//这里实际是等于 Integer total  = Integer.valueOf(99);

//自动拆箱
int totalprim = total; 
//这里实际是等于 int totalprim = total.intValue();

# 1.2、范围问题

Integer i = 400; 
Integer j = 400; 
System.out.println(i==j);  //false
Integer o = 12; 
Integer k = 12;
System.out.println(o==12);  //true

这是个很容易忽略但是必须要知道的范围问题。

上面提到,使用 Integer去创建数据,其实是一个Integer.valueOf 过程,Integer.valueOf 源码如下:

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

如果值的范围在-128到127之间,它就从高速缓存返回实例。

否则 new 一个Integer对象。new Integer 就是一个装箱的过程了,装箱的过程会创建对应的对象,这个会消耗内存,所以装箱的过程会增加内存的消耗,影响性能。

所以说最后是i 和 j 两个对象比较,内存地址不一样,结果就是false了。

# 1.3、==的值 比较问题

int a = 200;
Integer b = new Integer(200);
Integer b1 =new Integer(200);
Integer c = 200;
System.out.println(a == b); //true
System.out.println(a == c); //true
System.out.println(b == c); //false
System.out.println(b == b1); //false ,这是两个不同的对象

a==b,a==c,只要和基本数据类型(即 int)比较,Integer就会调用value.intValue()拆箱成基本数据类型,你也可以理解为:当有基本数据类型时,只比较值

b==c、b == b1,这两个是永远不会相等的,拆箱装箱只是针对基本数据类型的比较才有,Integer并不是基本数据类型,b、c、b1 三者存放的内存地址不一样,所以不相等。

# 1.4、Integer.parseInt()和Integer.valueOf()的区别

parseInt() 和 valueOf() 都是Integer 对象的方法。入参都是一个String字符串。

  • parseInt
public static int parseInt(String s) throws NumberFormatException

将字符串参数作为带符号十进制整数来转换。如果无法转换,抛出 NumberFormatException。

  • valueOf
public static Integer valueOf(String s) throws NumberFormatException

返回初始化为指定 String 值的新的 Integer 对象,如果无法转换,抛出 NumberFormatException。

eg:

String str = "-12";
int  num = Integer.parseInt(str);
System.out.println(num); // -12

Integer  num2 = Integer.valueOf(str);
System.out.println(num2); // -12

int num3 =Integer.parseInt("HaC"); //java.lang.NumberFormatException

int 与 Integer转换:

int a = A.intValue();
Integer A = Integer.valueOf(a);

Integer派别:Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。 Double派别:Double、Float的valueOf方法的实现是类似的。每次都返回不同的对象。

# 总结1:

①、无论如何,Integer 与 new Integer不会相等。不会经历拆箱过程,因为它们存放内存的位置不一样。

②、两个都是new出来的,即两个new Integer比较,一定不会相等。

③、两个都是非new出来的Integer,如果数在-128到127之间,则是true,否则为false。

④、int与Integer、new Integer()进行==比较时,结果永远为true,因为会把Integer自动拆箱为int,其实就是相当于两个int类型比较。

# 总结2:

  • Integer 继承了Object类,是对象类型,有自己的属性和方法,是 int 的包装类。int是java基本数据类型。
  • Integer默认值null,int默认值 0。
  • int 可以直接做运算,Integer 不能直接运算,拆箱转化为int才能进行运算。

# 2、其他包装类型

但是double有点不一样:(float也是一样)

Double的valueOf()和Integer的valueOf()不一样,Double是直接装箱的,new一个对象。

eg:

public class Main {
    public static void main(String[] args) {
        Double i1 = 100.0;
        Double i2 = 100.0;
        Double i3 = 200.0;
        Double i4 = 200.0;
        
        System.out.println(i1==i2); //false
        System.out.println(i3==i4); //false
    }
}

看一下 Double的valueOf()方法源码:

public static Double valueOf(double d) {
    return new Double(d); //直接new 对象
}

可以看到Double是直接new 一个对象的,并不像是Integer那样判断范围。

进行一个归类:

  1. Integer派别:Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。

  1. Double派别:Double、Float的valueOf方法的实现是类似的。每次都返回不同的对象。
阅读全文
×

(为防止恶意爬虫)
扫码或搜索:HelloCoder
发送:290992
即可永久解锁本站全部文章

解锁
#包装类型
上次更新: 2025-02-21 06:04:57
最近更新
01
《LeetCode 101》
02-21
02
IDEA、Golang、Pycharm破解安装
02-21
03
《LeetCode CookBook》
02-21
更多文章>
Theme by Vdoing | Copyright © 2020-2025 码农阿雨
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式