【JavaSE】【常用类02】 包装类

包装类其实就是将基本数据类型封装成类的一个属性,然后定义了一系列的方法来操作该基本类型的值
以Integer为例:


public final class Integer extends Number implements Comparable<Integer> {
...

//底层存储的数据
private final int value;

//构造器
public Integer(int value) {
    this.value = value;
}
...
}

1.为什么需要包装类?

(1)Java并不是纯面向对象的语言。

Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的。
基本数据类型有它的优势:性能(效率高,节省空间)

Java中哪些语法体现了其不是纯面向对象的语言?
1.基本数据类型
2.static语法

(2)使用包装类将基本数据类型转化成对象,便于操作。
- 集合的操作
- 使用Object类型接收任意类型的数据等
- 泛型实参
这时,我们就需要将基本数据类型数据转化为对象

2.基本数据类型和包装类的对应

在这里插入图片描述
其中有六个都是继承自java.lang.Number类:
在这里插入图片描述

3.自动装箱与自动拆箱

(1)JDK1.5之前需要手动装箱与拆箱,JDK1.5之后支持自动装箱与自动拆箱
(2)装箱:基本数据类型=>包装类对象
(3)拆箱:包装类对象=>基本数据类型

public class Main {
    public static void main(String[] args) {
    //自动装箱
    Integer total = 99;

    //自定拆箱
    int totalprim = total;
    }
}

(4)拆箱与装箱的本质

  • 装箱 valueOf()
Integer total = 99;
//执行上面那句代码的时候,系统为我们执行了: 
Integer total = Integer.valueOf(99);
  • 拆箱 xxxValue()
int totalprim = total; 
//执行上面那句代码的时候,系统为我们执行了: 
int totalprim = total.intValue();

(5)比较
1.当基本数据类型和对象类型进行比较的时候,会对包装类型进行自动拆箱

  • 包装类和基本数据类型比较 本质上是基本数据类型之间比较
  • 基本数据类型之间进行比较,所遵守的规则就是 自动向上转型
    @Test
    public void test02(){
        int a = 1;
        Integer b = 1;
        System.out.println(a == b);//true
		
		//自动拆箱后的基本数据类型之间进行比较,所遵守的规则就是 自动向上转型
		int c = 1;
        Double d = 1.0;
        System.out.println(c == d);//true
    }

2.包装类和包装类比较 遵循对象比较规则
对象类型用==进行比较,不是同一类型 编译直接报错

    @Test
    public void test03(){
        Integer a = 1;
        Double  b = 1.0;

        //System.out.println(a == b);   //编译不通过
        //todo 3.
        //  == 用于对象比较的时候,比较的是地址
        // 两个对象必须有父子关系或者同一类型才能比较

    }

4.自动装箱的缓存问题

1.代码演示现象
在使用自动装箱的时候,只有使用特定的包装类类型,以及一定的数值范围,获取的包装类对象是同一个

package _10_常用类.包装类;

import org.junit.Test;

public class _05_缓存问题 {
    @Test
    public void test01() {
        int a = 1;
        int b = 1;
        System.out.println(a==b);  //true

        int c = 130;
        int d = 130;
        System.out.println(c == d ); //true

    }


    //todo  
    // Byte.  Short.  Integer Long 等都有缓存对象
    // 缓存范围为-128~127
    @Test
    public void test02(){

        Integer e = 1;
        Integer f = 1;
        System.out.println(e==f);//true   比较的是地址

        Integer h = 130;
        Integer i = 130;
        System.out.println(h == i );//false  比较的是地址
    }
   
    
    // 仅限于装箱
    @Test
    public void test03(){

        Integer h1 = new Integer(120);
        Integer h2 = new Integer(120);
        System.out.println(h1 == h2);  //false


        Integer a1 = Integer.valueOf("2");
        Integer a2 = Integer.valueOf("2");
        System.out.println(a1 == a2); //true
    }
}

2.自动装箱源码解析
从前面,我们知道自动装箱,调用的是包装类的valueOf()方法

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

当自动装箱的基本数据类型在其上下限范围内,就返回缓存的对象!否则重新new 一个包装类对象!

3.IntegerCache类介绍
此类是Integer类的内部类,对于别的包装类也有自己的内部缓存类。
该缓存类定义了:
1.该数据类型的上下限取值
2.该包装类的数组 cache[],该数组装了-128到127的包装类对象

注意这个cache[] 缓存是静态常量,意味着存在于常量池中,并非堆中!

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() {}
}

4.总结
在自动装箱的时候,调用静态的valueOf()方法,此方法会判断数值是否在一定范围内,如果在范围内,直接返回内部类中缓存的数组中的对象,因此获取的是同一个包装类对象;如果不在这个范围内,直接new一个包装类对象;

关于所有包装类,缓存数据范围如下:
在这里插入图片描述

5.包装类的使用

(1)字符串 转 基本数据类型

public static int parseInt(String s) throws NumberFormatException {
    return parseInt(s,10);
}

(2)字符串、基本类型 转包装类

//1.基本类型转包装类
public Integer(int value) {
    this.value = value;
}

//2.字符串转包装类
public Integer(String s) throws NumberFormatException {
    this.value = parseInt(s, 10);
}

public static Integer valueOf(String s, int radix) throws NumberFormatException {
    return Integer.valueOf(parseInt(s,radix));
}

public static Integer valueOf(String s) throws NumberFormatException {
    return Integer.valueOf(parseInt(s, 10));
}

在这里插入图片描述

(3)获取该数据类型的取值范围

包装类中有静态常量,可以获取该类型数值的最大最小值:MIN_VALUE、MAX_VALUE
在这里插入图片描述

(4)包装类的其他方法

1、Integer类型
public static String toBinaryString(int i) //把十进制转成二进制
public static String toHexString(int i) //把十进制转成十六进制
public static String toOctalString(int i) //把十进制转成八进制

2、Character类型
public static char toUpperCase(char ch) //转成大写字母
public static char toLowerCase(char ch) //转成小写字母
其他的查看相关API文档即可

3、equals
按照包装的基本数据类型的值比较

4、compareTo
按照包装的基本数据类型的值比较

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值