Java随谈(六)我们真的理解 Java 里的整型吗?

整型是我们日常生活中最常用到的基础数据类型,看这篇文章之前,我想问:

我们真的像自己认为的那么理解 Java 内的整型吗?

也许看完本篇文章你就有自己的答案。

C 语言 提供了如下的整型

学习 Java 的整型之前,让我们看看它的前辈——C 语言的实现。

让我们更好地了解它的设计。

数据类型占用字节取值范围
signed char1 byte(8 bit)-2^7, 2^7-1
signed short2 byte(16 bit)-2^15, 2^15-1
signed int4 byte(32 bit)-2^31, 2^31-1
signed long4 byte(32 bit)-2^31, 2^31-1
signed long long8 byte(64 bit)-2^63, 2^63-1
unsigned char1 byte(8 bit)0, 2^8-1
unsigned short2 byte(16 bit)0, 2^16-1
unsigned int4 byte(32 bit)0, 2^32-1
unsigned long4 byte(32 bit)0, 2^32-1
unsigned long long8 byte(64 bit)0, 2^64-1

Java 提供了如下整型

Java 则简单了很多。

数据类型占用字节取值范围
byte1 byte(8 bit)-2^7, 2^7-1
short2 byte(16 bit)-2^15, 2^15-1
int4 byte(32 bit)-2^31, 2^31-1
long8 byte(64 bit)-2^63, 2^63-1

Java 和 C 整型的区别

  1. C的整型大小与操作系统的位数直接相关, 需要通过 sizeof 运算符先算出默认位数。 Java统一了位数。

  2. C的整型存在 unsigned 和 signed 的区别,而 Java 只有 signed。

    优势:更简单,不会遇到 unsigned 和 signed 整型进行运算的隐式转换问题。

    劣势:如果碰到 unsigned 的整型,会用存储容量更大的来存储。

    例子

    • unsigned byte 在 Java 中存储为 short
    • unsigned short 在 Java 中存储为 int
    • unsigned int 在 Java 中存储为 long
    • unsigned long 在 Java 中存储为 BigDecimal

    注: java 8 新增了 unsigned 相关的API,可以通过API计算。
    或采用 Guava 的 unsigned整数实现。 例如(com.google.common.primitives.UnsignedInteger)

  3. C 语言存在的整型溢出问题, 而 java.lang.Math包 提供了 xxxExact() 方法。

java 的装箱问题

原始数据类型占用字节包装类占用字节
byte1 byte(8 bit)Byte16 byte(128 bit)
short2 byte(16 bit)Short16 byte(128 bit)
int4 byte(32 bit)Integer16 byte(128 bit)
long8 byte(64 bit)Long16 byte(128 bit)

包装类的劣势

  1. 在数据密集型操作中,内存消耗会对性能产生巨大影响
  2. 基础类型存在默认值,而包装类可能存在 null,引起空指针异常
  3. 基础类型可以通过 == 判断大小,包装类型判断大小需要用 equals() 方法

包装类的优势

  1. 包装类会缓存实例,减小内存消耗。
    比如: Integer 会缓存 -128, 127内的实例
  2. 支持新特性,比如泛型,lambda表达式。
  3. 包装类提供了对象操作,封装了一些实用的方法
    比如:
    • Integer 继承了 Number 类, 可以和其他的 Number 子类进行转化
    • Integer 实现了 Comparable 接口
    • Integer 存在 unsigned API (java8)
    • Integer 提供了转化为二、八、十六进制的 API
    • Integer 提供了构造方法,并在其中校验了入参是否合法
    • Integer 提供了四则运算等算数API

Java 并不完美,它可以更好

从现在往回追溯,Java 的 Integer 事实上源于一个妥协。由于 java 号称完全面向对象,而在最初的版本中却存在 byte, short, int, long, char, boolean, float, double 这八种原始数据类型(primitive data types)。

在 Java 中我们无法写出类似下面的代码

    3.toString();

而在一些更加纯粹的面向对象语言,则可以实现上述代码。
例如 Scala

    3.toString();

引用

  1. Java Notes For Professionals.pdf
  2. Java 语言规范

感谢

希望对你有所帮助!

    原文作者:Kwanwooo
    原文地址: https://www.cnblogs.com/kwanwoo/p/16352760.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞