Java 8 中 Number 类及各子类所占字节数源码分析

这是《水煮 JDK 源码》系列 的第6篇文章,计划撰写100篇关于JDK源码相关的文章

基本的数据类型是在开发过程中经常使用的,而且它们都有着与之对应的包装类,基本的数据类型和包装类之间会自动转换,即所谓的自动装箱和拆箱,但是在使用的时候,我们可能并不会过多的去关注这些包装类的父类,下面结合具体的源码来分析一下它们的父类 Number 类。

1、Number 类

Number 类位于 java.lang 下,实现了 java.io.Serializable 接口,它是一个抽象类,是所有可以转换为数值的类的父类,比如 byteshortintfloatdouble这些基本的数据类型,类定义如下:

public abstract class Number implements java.io.Serializable {
    /** 以 int 形式返回指定数字的值,可能涉及到四舍五入或者截断 */
    public abstract int intValue();

    /** 以 long 形式返回指定数字的值,可能涉及到四舍五入或者截断 */
    public abstract long longValue();

    /** 以 float 形式返回指定数字的值,可能涉及到四舍五入 */
    public abstract float floatValue();

    /** 以 double 形式返回指定数字的值,可能涉及到四舍五入 */
    public abstract double doubleValue();

    /** 以 byte 形式返回指定数字的值,可能涉及到四舍五入或者截断 */
    public byte byteValue() {
        return (byte)intValue();
    }

    /** 以 short 形式返回指定数字的值,可能涉及到四舍五入或者截断 */
    public short shortValue() {
        return (short)intValue();
    }

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = -8742448824652078965L;
}

该类定义了 4个抽象方法,分别用于获取 intlongfloatdouble 类型的值,其中 byteshort 类型的值可以通过 int 值进行强制类型转换获取(这种由范围大的类型转换为范围小的类型,实际过程中可能会存在精度丢失)。

在平时开发的过程中,我们可能很少直接使用到 Number 类,更多是使用它的子类,比如基本的数据类型 byteshortintlongfloatdouble这些,或者是它们各自对应的包装类型 ByteShortIntLongFloatDouble,下面来分别看看这些基本数据类型的包装类的定义。

(1)Byte 类定义

public final class Byte extends Number implements Comparable<Byte>

(2)Short 类定义

public final class Short extends Number implements Comparable<Short>

(3)Integer 类定义

public final class Integer extends Number implements Comparable<Integer>

(4)Long 类定义

public final class Long extends Number implements Comparable<Long>

(5)Float 类定义

public final class Float extends Number implements Comparable<Float> 

(6)Double 类定义

public final class Double extends Number implements Comparable<Double> 

这些基本的数据类型,其类的定义其实都是一样的,都继承于 Number 抽象类,并且实现了 Comparable 比较接口,UML 类图如下:

::: hljs-center

image20220801102918311.png

:::

Number 类除了是基本数据类型的父类,同时也是 java.util.concurrent.atomic 包下 Atomic 原子类的父类,相关 UML 类图如下:

::: hljs-center

image20220802100605107.png

:::

2、Number 子类所占字节数

Number 类拥有众多的子类,比如常见的 ByteShortIntLongFloatDouble,这些基本数据类型所占用的字节数又是多少呢?

在每一个子类中,都会存在两个静态常量 SIZEBYTES,分别代表着该类型数值所占的 bit 位数和字节数,其中 SIZE 常量是从 JDK 1.5 版本新增的,而 BYTES 常量是从 JDK 1.8 新增的,下面结合各个子类的源码来分析一下。

2.1 Byte 类
/** byte 类型所占的 bit 位数为 8,也就是 1 byte = 8 bits */
public static final int SIZE = 8;

/** byte 类型所占的字节数,等于 1 */
public static final int BYTES = SIZE / Byte.SIZE;
2.2 Short 类
/** short 类型所占的 bit 位数为16,也就是 1 short = 16 bits */
public static final int SIZE = 16;

/** short 类型所占的字节数,等于 2 */
public static final int BYTES = SIZE / Byte.SIZE;
2.3 Integer 类
/** int 类型所占的 bit 位数为32,也就是 1 int = 32 bits */
@Native public static final int SIZE = 32;

/** int 类型所占的字节数,等于 4 */
public static final int BYTES = SIZE / Byte.SIZE;
2.4 Long 类
/** long 类型所占的 bit 位数为64,也就是 1 long = 64 bits */
@Native public static final int SIZE = 64;

/** long 类型所占的字节数,等于 8 */
public static final int BYTES = SIZE / Byte.SIZE;
2.5 Float 类
/** float 类型所占的 bit 位数为32,也就是 1 float = 32 bits */
public static final int SIZE = 32;

/** float 类型所占的字节数,等于 4 */
public static final int BYTES = SIZE / Byte.SIZE;
2.6 Double 类
/** double 类型所占的 bit 位数为64,也就是 1 double = 64 bits */
public static final int SIZE = 64;

/** double 类型所占的字节数,等于 8 */
public static final int BYTES = SIZE / Byte.SIZE;

从上面的源码分析可以看出,各种数据类型所占的字节大小都可以通过源码进行查看,其中 IntegerLong 类型的 SIZE 字段定义和其他的类不太一样,它们使用了一个 @Native 注解修饰,那么这个 @Native 注解又是什么用途呢?下面来看看其定义:

@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.SOURCE)
public @interface Native {
}

@Native 注解位于 java.lang.annotation 包中,从其定义可以看出,这个注解主要用于修饰字段的,表示被修饰的字段可以被本地代码引用,并且常常被代码生成工具所使用,比如生成头文件信息,该注解是从 JDK 1.8 版本新增的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值