这是《水煮 JDK 源码》系列 的第6篇文章,计划撰写100篇关于JDK源码相关的文章
基本的数据类型是在开发过程中经常使用的,而且它们都有着与之对应的包装类,基本的数据类型和包装类之间会自动转换,即所谓的自动装箱和拆箱,但是在使用的时候,我们可能并不会过多的去关注这些包装类的父类,下面结合具体的源码来分析一下它们的父类 Number 类。
1、Number 类
Number 类位于 java.lang 下,实现了 java.io.Serializable 接口,它是一个抽象类,是所有可以转换为数值的类的父类,比如 byte、short、int、float 、double这些基本的数据类型,类定义如下:
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个抽象方法,分别用于获取 int、long、float、double 类型的值,其中 byte 和 short 类型的值可以通过 int 值进行强制类型转换获取(这种由范围大的类型转换为范围小的类型,实际过程中可能会存在精度丢失)。
在平时开发的过程中,我们可能很少直接使用到 Number 类,更多是使用它的子类,比如基本的数据类型 byte、short、int、long、float 、double这些,或者是它们各自对应的包装类型 Byte、Short、Int、Long、Float 、Double,下面来分别看看这些基本数据类型的包装类的定义。
(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

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

:::
2、Number 子类所占字节数
Number 类拥有众多的子类,比如常见的 Byte、Short、Int、Long、Float 、Double,这些基本数据类型所占用的字节数又是多少呢?
在每一个子类中,都会存在两个静态常量 SIZE 和 BYTES,分别代表着该类型数值所占的 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;
从上面的源码分析可以看出,各种数据类型所占的字节大小都可以通过源码进行查看,其中 Integer 和 Long 类型的 SIZE 字段定义和其他的类不太一样,它们使用了一个 @Native 注解修饰,那么这个 @Native 注解又是什么用途呢?下面来看看其定义:
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.SOURCE)
public @interface Native {
}
@Native 注解位于 java.lang.annotation 包中,从其定义可以看出,这个注解主要用于修饰字段的,表示被修饰的字段可以被本地代码引用,并且常常被代码生成工具所使用,比如生成头文件信息,该注解是从 JDK 1.8 版本新增的。










