我们真的理解 Java 里的整型吗

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

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

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

C 语言 提供了如下的整型

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

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

数据类型 占用字节 取值范围
signed char 1 byte(8 bit) -2^7, 2^7-1
signed short 2 byte(16 bit) -2^15, 2^15-1
signed int 4 byte(32 bit) -2^31, 2^31-1
signed long 4 byte(32 bit) -2^31, 2^31-1
signed long long 8 byte(64 bit) -2^63, 2^63-1
unsigned char 1 byte(8 bit) 0, 2^8-1
unsigned short 2 byte(16 bit) 0, 2^16-1
unsigned int 4 byte(32 bit) 0, 2^32-1
unsigned long 4 byte(32 bit) 0, 2^32-1
unsigned long long 8 byte(64 bit) 0, 2^64-1

Java 提供了如下整型

Java 则简单了很多。

数据类型 占用字节 取值范围
byte 1 byte(8 bit) -2^7, 2^7-1
short 2 byte(16 bit) -2^15, 2^15-1
int 4 byte(32 bit) -2^31, 2^31-1
long 8 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 的装箱问题

原始数据类型 占用字节 包装类 占用字节
byte 1 byte(8 bit) Byte 16 byte(128 bit)
short 2 byte(16 bit) Short 16 byte(128 bit)
int 4 byte(32 bit) Integer 16 byte(128 bit)
long 8 byte(64 bit) Long 16 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 语言规范

感谢

希望对你有所帮助!

Java随谈(六)## 我们真的理解 Java 里的整型吗?的更多相关文章

  1. 你真的理解Java 注解吗?

    你真的理解Java 注解吗? 1.什么是注解? 官方解释: Java 注解用于为 Java 代码提供元数据.作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的.Java ...

  2. Java四种引用--《深入理解Java虚拟机》学习笔记及个人理解(四)

    Java四种引用--<深入理解Java虚拟机>学习笔记及个人理解(四) 书上P65. StrongReference(强引用) 类似Object obj = new Object() 这类 ...

  3. Java基础系列1:深入理解Java数据类型

    Java基础系列1:深入理解Java数据类型 当初学习计算机的时候,教科书中对程序的定义是:程序=数据结构+算法,Java基础系列第一篇就聊聊Java中的数据类型. 本篇聊Java数据类型主要包括四个 ...

  4. Java内存管理-你真的理解Java中的数据类型吗(十)

    勿在流沙筑高台,出来混迟早要还的. 做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 作为Java程序员,Java 的数据类型这个是一定要知道的! 但是不管是那种数据类型最 ...

  5. java提高篇(二)-----理解java的三大特性之继承

    在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句 ...

  6. 夯实Java基础系列10:深入理解Java中的异常体系

    目录 为什么要使用异常 异常基本定义 异常体系 初识异常 异常和错误 异常的处理方式 "不负责任"的throws 纠结的finally throw : JRE也使用的关键字 异常调 ...

  7. java提高篇(三)-----理解java的三大特性之多态

    面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...

  8. 夯实Java基础系列11:深入理解Java中的回调机制

    目录 模块间的调用 多线程中的"回调" Java回调机制实战 实例一 : 同步调用 实例二:由浅入深 实例三:Tom做题 参考文章 微信公众号 Java技术江湖 个人公众号:黄小斜 ...

  9. 夯实Java基础系列13:深入理解Java中的泛型

    目录 泛型概述 一个栗子 特性 泛型的使用方式 泛型类 泛型接口 泛型通配符 泛型方法 泛型方法的基本用法 类中的泛型方法 泛型方法与可变参数 静态方法与泛型 泛型方法总结 泛型上下边界 泛型常见面试 ...

随机推荐

  1. vue中判断页面滚动开始和结束

    参考链接:https://www.jianshu.com/p/adad39705ced    和  https://blog.csdn.net/weixin_44309374/article/deta ...

  2. 在create-react-app使用less与antd按需加载

    使用antd按需加载 使用react-app-rewired对 create-react-app 的默认配置进行自定义 yarn add react-app-rewired --dev /* pack ...

  3. C语言之:结构体动态分配内存(利用结构体数组保存不超过10个学生的信息,每个学生的信息包括:学号、姓名和三门课(高数、物理和英语 )的成绩和平均分(整型)。)

    题目内容: 利用结构体数组保存不超过10个学生的信息,每个学生的信息包括:学号.姓名和三门课(高数.物理和英语 )的成绩和平均分(整型). 编写程序,从键盘输入学生的人数,然后依次输入每个学生的学号. ...

  4. matplotlib---Annotation标注

    import numpy as np import matplotlib.pyplot as plt x = np.linspace(-3, 3, 50) y = 2 * x + 1 plt.figu ...

  5. Unity通过脚本创建Mesh(网格)

    ##1.创建一个带Mesh的物体 Unity中的网格作为组件不能脱离物体单独存在 新建脚本CreateMesh public class CreateMesh: MonoBehaviour { voi ...

  6. 新手入门C语言第十章:C作用域规则

    C 作用域规则任何一种编程中,作用域是程序中定义的变量所存在的区域,超过该区域变量就不能被访问.C 语言中有三个地方可以声明变量: 在函数或块内部的局部变量 在所有函数外部的全局变量 在形式参数的函数 ...

  7. Halo 开源项目学习(二):实体类与数据表

    基本介绍 Halo 项目中定义了一些实体类,用于存储博客中的关键数据,如用户信息.文章信息等.在深入学习 Halo 的设计理念与实现过程之前,不妨先学习一下一个完整的博客系统都由哪些元素组成. 实体类 ...

  8. Vue3 setup详解

    setup执行的时机 在beforeCreate之前执行(一次),此时组件对象还没创建: this是undefined,不能通过this来访问data/computed/methods/props: ...

  9. IOC容器--1.12. 基于 Java 的容器配置

    用Java的方式配置Spring ,不使用Spring的XML配置,全权交给Java来做 JavaConfig是Spring的一个子项目,在Sring 4  之后成为核心功能 这种纯Java的配置方式 ...

  10. STM32 DMA(UART)

    转载自https://blog.csdn.net/as480133937/article/details/104827639/