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

Posted 然笑后端

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Number 类及各子类所占字节数源码分析相关的知识,希望对你有一定的参考价值。

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

:::

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

::: hljs-center

:::

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 版本新增的。

以上是关于Number 类及各子类所占字节数源码分析的主要内容,如果未能解决你的问题,请参考以下文章

java如何生成字节码文件?

在c语言中,int,char,short三种类型数据在内存中所占的字节数由啥决定

JVM:深入分析Java字节码-上

中文字符与编码格式占位问题

指针变量所占的字节数

抽象类及抽象类