我们真的理解 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. JavaScript的使用以及JS常用函数(JS 遍历数组和集合)

    JavaScript入门 学习总结 1. 什么是 JavaScript 2. JavaScript 的特点 3. JS的使用 编写位置 基本语法 变量 打印变量 数据类型 innerHTML和inne ...

  2. python---运算符和编码

    格式化输出 在输出数据时,会有用户需要输入的信息被输出,没办法预先知道,这就需要使用格式化输出.先在相应位置放置一个占位符,再把字符串里的占位符与外部的变量做个映射关系. name = input(& ...

  3. centos6的yum源更新版本

    概述 centos6系统从2020年12月1号开始不再维护,官方的yum源不再可用,同时国内的阿里云镜像和163镜像也都不再可用. 但是我们有一些老的服务器仍然在使用centos6系统版本,依赖库的安 ...

  4. 几种比较经典的波形及其FFT变换(正弦波,三角波,方波和锯齿波)

    之前上学时我的信号学得最差了,主要原因还是我高数学得不怎么样.可能是人总敬畏自己最不会的,所以我觉得我学过诸多科目中,数学是最博大精深而最妙的,从最开始的一次函数到反比例函数,二次三次函数和双曲线,椭 ...

  5. NodeJS学习day1

    今天主要学习的IO操作 const fs = require('fs') fs.readFile('./files/11.txt','utf-8',function(err,daraStr){ //读 ...

  6. 使用Harr特征的级联分类器实现目标检测

    前言  最近在学习人脸的目标检测任务时,用了Haar人脸检测算法,这个算法实现起来太简洁了,读入个.xml,调用函数就能用.但是深入了解我发现这个算法原理很复杂,也很优秀.究其根源,于是我找了好些篇相 ...

  7. 轻量迅捷时代,Vite 与Webpack 谁赢谁输

    你知道Vite和Webpack吗?也许有不少"程序猿"对它们十分熟悉. Webpack Webpack是一个JavaScript应用程序的静态模块打包工具,它会对整个应用程序进行依 ...

  8. Fastjson JdbcRowSetImpl利用链学习

    JdbcRowSetImpl 接着继续学习fastjson的第二条链JdbcRowSetImpl,主要是利用jndi注入达到的攻击,而且没有什么利用限制,而且其原理就是setter的自动调用,具体se ...

  9. Linux下安装并使用jumpserver跳板机

    堡垒机介绍: 官方网站:https://www.jumpserver.org/ 在一个特定网络环境下,为了保障网络和数据不受外界入侵和破坏,而运用各种技术手段实时收集和监控网络环境中每一个组成部分的系 ...

  10. 数据结构篇(3)ts 实现双向链表

    如今终于到了双向链表了,此前在Node结构中的prev指针终于派上了用场.由于双向链表多了一个前向指针,所以有些操作和单向链表比较起来反而更加的简单. class DbList extends Cir ...