Java 数据类型自动转换中的溢出情况

本贴最后更新于 1831 天前,其中的信息可能已经水流花落

Java 程序中要求参与的计算的数据,必须要保证数据类型的一致性,如果数据类型不一致将发生类型的转换

数据类型的自动转换

一个 int 类型变量和一个 byte 类型变量进行加法运算

int i = 1; byte b = 2;

运算结果,变量的类型将是 int 类型,这就是出现了数据类型的自动类型转换现象

public static void main(String[] args) { int i = 1; byte b = 2; // byte x = b + i; // 报错 //int类型和byte类型运算,结果是int类型 int j = b + i; System.out.println(j); }

自动转换:将取值范围小的类型自动提升为取值范围大的类型

我们先看看 Java 中的基本数据类型

Types Default Size Range
byte 0 8 bits -128 to 127
short 0 16 bits -32768 to 32767
int 0 32 bits -2147483648 to 2147483647
float 0.0f 32 bits ±1.4E-45 to ±3.4028235E+38
long 0L 64 bits -9223372036854775808 to 9223372036854775807
double 0.0d 64 bits ±4.9E-324 to ±1.7976931348623157E+308
--- --- --- ---
boolean false 1bits  NA
char ‘\u0000’ 16 bits \u0000 to \uFFFF

自动转换如下图
image.png

蓝色箭头指向自动转换时不会造成数据丢失,红色箭头指向在进行自动转换时候则要注意可能会有数据丢失的问题。

结合上文的表和图我们可以发现 自动转换是范围小的可以自动转换为范围大的基本数据类型

byte,short,char-->int-->long-->float-->double

注意:自动转换要提防数据溢出问题,自动转换时数据溢出也是一些企业面试题的考点

public class hello {
public static void main(String[] args) {
int x = 100000000;
int y = 100;
long z = x*y;
System.out.println(z);
}
}

输出结果是:1410065408

如果这种情况出现在金融项目中,一个程序员就可能给公司干倒闭
image.png

为什么编译都通过了计算出来的答案却是错的呢?
为什么和正确答案 10000000000 相差了这么多呢?
这不是肯定不是巧合!

我们再来回过头来看看 int 的取值范围

int 的取值范围 -2147483648 to 2147483647

x*y 的正确结果 199000000000,妈耶!不小心玩现了!

IDE 也没有提示我强制类型转换呀!

x*y 的计算结果超过了 int 的取值范围,我明明记得有自动转换这个东西的,再说 IDE 也没有提示我强制类型转换呀!难道这个东西没起作用?

自动类型转换当然起作用了,不过是在赋值的时候起作用的,x 和 y 都是 int 数据类型,两个 int 相乘 结果还是 int 类型的,然后赋值给 long 类型的 z 在这个时候自动类型转换生效将计算结果(尽管计算结果可能是错的)转换为 long 类型赋值给 z。

溢出

当变量的数据类型所提供的位数无法适应某个值时,就会发生溢出(上溢)或下溢。就像往水桶里装水,水满则溢,变量也是这样,如果要存储的值超过了变量所能提供的位数,就会出现问题。

先来看一个例子

假设在一个使用了 2 个字节内存的 short int 类型变量中存储了以下值:

image.png

现在高阶位我标红的高阶位方里面是 0,表示正数

学过计算机组成原理而且课上没睡觉的同学已经口算(我不信)算出来了,这是 32 767 的二进制表示。
这也是 2 个字节所能表示的该数据类型的最大值。

现在我们再让它加 1 就会变成下面这个情况

image.png

我的天呐!它变性了!口误。。。它变形了,它变成了负值,也就是 -32 768

这不是 32768 而是-32768,二进制 1 流入到高阶位,改变了正负号
。(这种情况属于数据溢出(上溢))

我们把这个图反着来试一试

image.png

-32768 减去 1 变成了 32767

你一定发现了什么!

当一个变量保存的数值在其数据类型负值范围的最远端(即最小负值),那么当它被减去 1 时,其高位中的 1 将变为 0,结果数将被解释为正数

当一个变量保存的数值在其数据类型正值范围的最远端(即最大值),那么当它被加 1 时,其高位中的 0 将变为 1,结果数将被解释为负数

发现了规律 就好办了,以后就能盘它!

你 duck 不必去纠结 溢出值的计算,只需要记住溢出对我们得程序没有一点好处,它就是一个 bad word,一些骇客利用内存溢出来实现攻击或入侵,我们要防止溢出情况的发生.

我们的 IDE 通常可以立即发现你在基本数据类型的范围取值的边界进行 +/-的骚操作,会实时告知你此处需要强制类型转换(就是提醒会有精度丢失或计算不准确的情况发生),但是当你在赋值时候直接进行俩个变量的乘法操作时候,至少目前已知的 IDE 是不会检测出来的.

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3192 引用 • 8214 回帖 • 2 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • Excel
    31 引用 • 28 回帖
  • Vue.js

    Vue.js(读音 /vju ː/,类似于 view)是一个构建数据驱动的 Web 界面库。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

    267 引用 • 666 回帖 • 3 关注
  • 星云链

    星云链是一个开源公链,业内简单的将其称为区块链上的谷歌。其实它不仅仅是区块链搜索引擎,一个公链的所有功能,它基本都有,比如你可以用它来开发部署你的去中心化的 APP,你可以在上面编写智能合约,发送交易等等。3 分钟快速接入星云链 (NAS) 测试网

    3 引用 • 16 回帖 • 1 关注
  • ReactiveX

    ReactiveX 是一个专注于异步编程与控制可观察数据(或者事件)流的 API。它组合了观察者模式,迭代器模式和函数式编程的优秀思想。

    1 引用 • 2 回帖 • 169 关注
  • LaTeX

    LaTeX(音译“拉泰赫”)是一种基于 ΤΕΧ 的排版系统,由美国计算机学家莱斯利·兰伯特(Leslie Lamport)在 20 世纪 80 年代初期开发,利用这种格式,即使使用者没有排版和程序设计的知识也可以充分发挥由 TeX 所提供的强大功能,能在几天,甚至几小时内生成很多具有书籍质量的印刷品。对于生成复杂表格和数学公式,这一点表现得尤为突出。因此它非常适用于生成高印刷质量的科技和数学类文档。

    12 引用 • 54 回帖 • 23 关注
  • 外包

    有空闲时间是接外包好呢还是学习好呢?

    26 引用 • 232 回帖
  • 又拍云

    又拍云是国内领先的 CDN 服务提供商,国家工信部认证通过的“可信云”,乌云众测平台认证的“安全云”,为移动时代的创业者提供新一代的 CDN 加速服务。

    20 引用 • 37 回帖 • 564 关注
  • 负能量

    上帝为你关上了一扇门,然后就去睡觉了....努力不一定能成功,但不努力一定很轻松 (° ー °〃)

    88 引用 • 1235 回帖 • 408 关注
  • ngrok

    ngrok 是一个反向代理,通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道。

    7 引用 • 63 回帖 • 639 关注
  • NGINX

    NGINX 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。 NGINX 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。

    315 引用 • 547 回帖 • 1 关注
  • 书籍

    宋真宗赵恒曾经说过:“书中自有黄金屋,书中自有颜如玉。”

    76 引用 • 389 回帖
  • Sublime

    Sublime Text 是一款可以用来写代码、写文章的文本编辑器。支持代码高亮、自动完成,还支持通过插件进行扩展。

    10 引用 • 5 回帖 • 1 关注
  • Flutter

    Flutter 是谷歌的移动 UI 框架,可以快速在 iOS 和 Android 上构建高质量的原生用户界面。 Flutter 可以与现有的代码一起工作,它正在被越来越多的开发者和组织使用,并且 Flutter 是完全免费、开源的。

    39 引用 • 92 回帖 • 3 关注
  • webpack

    webpack 是一个用于前端开发的模块加载器和打包工具,它能把各种资源,例如 JS、CSS(less/sass)、图片等都作为模块来使用和处理。

    41 引用 • 130 回帖 • 253 关注
  • gRpc
    11 引用 • 9 回帖 • 85 关注
  • Facebook

    Facebook 是一个联系朋友的社交工具。大家可以通过它和朋友、同事、同学以及周围的人保持互动交流,分享无限上传的图片,发布链接和视频,更可以增进对朋友的了解。

    4 引用 • 15 回帖 • 435 关注
  • 单点登录

    单点登录(Single Sign On)是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

    9 引用 • 25 回帖
  • Chrome

    Chrome 又称 Google 浏览器,是一个由谷歌公司开发的网页浏览器。该浏览器是基于其他开源软件所编写,包括 WebKit,目标是提升稳定性、速度和安全性,并创造出简单且有效率的使用者界面。

    62 引用 • 289 回帖
  • Docker

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的操作系统上。容器完全使用沙箱机制,几乎没有性能开销,可以很容易地在机器和数据中心中运行。

    493 引用 • 928 回帖
  • ZeroNet

    ZeroNet 是一个基于比特币加密技术和 BT 网络技术的去中心化的、开放开源的网络和交流系统。

    1 引用 • 21 回帖 • 633 关注
  • NetBeans

    NetBeans 是一个始于 1997 年的 Xelfi 计划,本身是捷克布拉格查理大学的数学及物理学院的学生计划。此计划延伸而成立了一家公司进而发展这个商用版本的 NetBeans IDE,直到 1999 年 Sun 买下此公司。Sun 于次年(2000 年)六月将 NetBeans IDE 开源,直到现在 NetBeans 的社群依然持续增长。

    78 引用 • 102 回帖 • 704 关注
  • 微服务

    微服务架构是一种架构模式,它提倡将单一应用划分成一组小的服务。服务之间互相协调,互相配合,为用户提供最终价值。每个服务运行在独立的进程中。服务于服务之间才用轻量级的通信机制互相沟通。每个服务都围绕着具体业务构建,能够被独立的部署。

    96 引用 • 155 回帖 • 2 关注
  • Redis

    Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。从 2010 年 3 月 15 日起,Redis 的开发工作由 VMware 主持。从 2013 年 5 月开始,Redis 的开发由 Pivotal 赞助。

    286 引用 • 248 回帖 • 28 关注
  • OpenResty

    OpenResty 是一个基于 NGINX 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

    17 引用 • 44 关注
  • 微信

    腾讯公司 2011 年 1 月 21 日推出的一款手机通讯软件。用户可以通过摇一摇、搜索号码、扫描二维码等添加好友和关注公众平台,同时可以将自己看到的精彩内容分享到微信朋友圈。

    132 引用 • 796 回帖
  • RESTful

    一种软件架构设计风格而不是标准,提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

    30 引用 • 114 回帖 • 10 关注
  • 强迫症

    强迫症(OCD)属于焦虑障碍的一种类型,是一组以强迫思维和强迫行为为主要临床表现的神经精神疾病,其特点为有意识的强迫和反强迫并存,一些毫无意义、甚至违背自己意愿的想法或冲动反反复复侵入患者的日常生活。

    15 引用 • 161 回帖 • 1 关注