前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入理解 Java 基本数据类型

深入理解 Java 基本数据类型

作者头像
静默虚空
发布2019-05-25 16:35:42
1.1K0
发布2019-05-25 16:35:42
举报

深入理解 Java 基本数据类型

? 本文已归档到:「blog

  • 数据类型分类
    • 值类型
    • 值类型和引用类型的区别
  • 数据转换
    • 自动转换
    • 强制转换
  • 装箱和拆箱
    • 包装类、装箱、拆箱
    • 自动装箱、自动拆箱
    • 装箱、拆箱的应用和注意点
  • 小结
  • 参考资料

数据类型分类

Java 中的数据类型有两类:

  • 值类型(又叫内置数据类型,基本数据类型)
  • 引用类型(除值类型以外,都是引用类型,包括 String、数组)

值类型

Java 语言提供了 8 种基本类型,大致分为 4

  • 整数型
    • byte - 8 位。
    • short - 16 位。
    • int - 32 位。
    • long - 64 位,赋值时一般在数字后加上 lL
  • 浮点型
    • float - 32 位,直接赋值时必须在数字后加上 fF
    • double - 64 位,赋值时一般在数字后加 dD
  • 字符型
    • char - 16 位,存储 Unicode 码,用单引号赋值。
  • 布尔型
    • boolean - 只有 true 和 false 两个取值。

值类型和引用类型的区别

  • 从概念方面来说
    • 基本类型:变量名指向具体的数值。
    • 引用类型:变量名指向存数据对象的内存地址。
  • 从内存方面来说
    • 基本类型:变量在声明之后,Java 就会立刻分配给他内存空间。
    • 引用类型:它以特殊的方式(类似 C 指针)向对象实体(具体的值),这类变量声明时不会分配内存,只是存储了一个内存地址。
  • 从使用方面来说
    • 基本类型:使用时需要赋具体值,判断时使用 == 号。
    • 引用类型:使用时可以赋 null,判断时使用 equals 方法。

? 扩展阅读:Java 基本数据类型和引用类型 这篇文章对于基本数据类型和引用类型的内存存储讲述比较生动。

数据转换

Java 中,数据类型转换有两种方式:

  • 自动换行
  • 强制转换

自动转换

一般情况下,定义了某数据类型的变量,就不能再随意转换。但是 JAVA 允许用户对基本类型做有限度的类型转换。

如果符合以下条件,则 JAVA 将会自动做类型转换:

  • 由小数据转换为大数据 显而易见的是,“小”数据类型的数值表示范围小于“大”数据类型的数值表示范围,即精度小于“大”数据类型。 所以,如果“大”数据向“小”数据转换,会丢失数据精度。比如:long 转为 int,则超出 int 表示范围的数据将会丢失,导致结果的不确定性。 反之,“小”数据向“大”数据转换,则不会存在数据丢失情况。由于这个原因,这种类型转换也称为扩大转换。 这些类型由“小”到“大”分别为:(byte,short,char) < int < long < float < double。 这里我们所说的“大”与“小”,并不是指占用字节的多少,而是指表示值的范围的大小。
  • 转换前后的数据类型要兼容 由于 boolean 类型只能存放 true 或 false,这与整数或字符是不兼容的,因此不可以做类型转换。
  • 整型类型和浮点型进行计算后,结果会转为浮点类型

示例:

代码语言:javascript
复制
long x = 30;
float y = 14.3f;
System.out.println("x/y = " + x/y);

输出:

代码语言:javascript
复制
x/y = 1.9607843

可见 long 虽然精度大于 float 类型,但是结果为浮点数类型。

强制转换

在不符合自动转换条件时或者根据用户的需要,可以对数据类型做强制的转换。

强制转换使用括号 ()

引用类型也可以使用强制转换。

示例:

代码语言:javascript
复制
float f = 25.5f;
int x = (int)f;
System.out.println("x = " + x);

装箱和拆箱

包装类、装箱、拆箱

Java 中为每一种基本数据类型提供了相应的包装类,如下:

代码语言:javascript
复制
Byte <-> byte
Short <-> short
Integer <-> int
Long <-> long
Float <-> float
Double <-> double
Character <-> char
Boolean <-> boolean

引入包装类的目的就是:提供一种机制,使得基本数据类型可以与引用类型互相转换

基本数据类型与包装类的转换被称为装箱拆箱

  • 装箱(boxing)是将值类型转换为引用类型。例如:intInteger
    • 装箱过程是通过调用包装类的 valueOf 方法实现的。
  • 拆箱(unboxing)是将引用类型转换为值类型。例如:Integerint
    • 拆箱过程是通过调用包装类的 xxxValue 方法实现的。(xxx 代表对应的基本数据类型)。

自动装箱、自动拆箱

基本数据(Primitive)型的自动装箱(boxing)拆箱(unboxing)自 JDK 5 开始提供的功能。

JDK 5 之前的形式:

代码语言:javascript
复制
Integer i1 = new Integer(10); // 非自动装箱

JDK 5 之后:

代码语言:javascript
复制
Integer i2 = 10; // 自动装箱

Java 对于自动装箱和拆箱的设计,依赖于一种叫做享元模式的设计模式(有兴趣的朋友可以去了解一下源码,这里不对设计模式展开详述)。

? 扩展阅读:深入剖析 Java 中的装箱和拆箱 结合示例,一步步阐述装箱和拆箱原理。

装箱、拆箱的应用和注意点

装箱、拆箱应用场景
  • 一种最普通的场景是:调用一个含类型为 Object 参数的方法,该 Object 可支持任意类型(因为 Object 是所有类的父类),以便通用。当你需要将一个值类型(如 int)传入时,需要使用 Integer 装箱。
  • 另一种用法是:一个非泛型的容器,同样是为了保证通用,而将元素类型定义为 Object。于是,要将值类型数据加入容器时,需要装箱。
  • == 运算符的两个操作,一个操作数是包装类,另一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)。

示例:

代码语言:javascript
复制
Integer i1 = 10; // 自动装箱
Integer i2 = new Integer(10); // 非自动装箱
Integer i3 = Integer.valueOf(10); // 非自动装箱
int i4 = new Integer(10); // 自动拆箱
int i5 = i2.intValue(); // 非自动拆箱
System.out.println("i1 = [" + i1 + "]");
System.out.println("i2 = [" + i2 + "]");
System.out.println("i3 = [" + i3 + "]");
System.out.println("i4 = [" + i4 + "]");
System.out.println("i5 = [" + i5 + "]");
System.out.println("i1 == i2 is [" + (i1 == i2) + "]");
System.out.println("i1 == i4 is [" + (i1 == i4) + "]"); // 自动拆箱
// Output:
// i1 = [10]
// i2 = [10]
// i3 = [10]
// i4 = [10]
// i5 = [10]
// i1 == i2 is [false]
// i1 == i4 is [true]

示例说明: 上面的例子,虽然简单,但却隐藏了自动装箱、拆箱和非自动装箱、拆箱的应用。从例子中可以看到,明明所有变量都初始化为数值 10 了,但为何会出现 i1 == i2 is [falsei1 == i4 is [true] ? 原因在于:

  • i1、i2 都是包装类,使用 == 时,Java 将它们当做两个对象,而非两个 int 值来比较,所以两个对象自然是不相等的。正确的比较操作应该使用 equals 方法。
  • i1 是包装类,i4 是基础数据类型,使用 == 时,Java 会将两个 i1 这个包装类对象自动拆箱为一个 int 值,再代入到 == 运算表达式中计算;最终,相当于两个 int 进行比较,由于值相同,所以结果相等。
装箱、拆箱应用注意点
  1. 装箱操作会创建对象,频繁的装箱操作会造成不必要的内存消耗,影响性能。所以应该尽量避免装箱。
  2. 基础数据类型的比较操作使用 ==,包装类的比较操作使用 equals 方法。

小结

(1)Java 中的数据类型有两类:

  • 值类型(byteshortintlongfloatdoublecharboolean
  • 引用类型(除值类型以外,都是引用类型,包括 String、数组)

(2)Java 中,数据类型转换有两种方式:

  • 自动换行
  • 强制转换

强制转换使用括号 ()

基础数据类型可以自动转换,转换原则如下:

  • 由小数据转换为大数据
  • 转换前后的数据类型要兼容
  • 整型类型和浮点型进行计算后,结果会转为浮点类型

(3)包装类有如下种类:

代码语言:javascript
复制
Byte <-> byte
Short <-> short
Integer <-> int
Long <-> long
Float <-> float
Double <-> double
Character <-> char
Boolean <-> boolean

(4)什么是装箱、拆箱

  • 装箱(boxing)是将值类型转换为引用类型。例如:intInteger
    • 装箱过程是通过调用包装类的 valueOf 方法实现的。
  • 拆箱(unboxing)是将引用类型转换为值类型。例如:Integerint
    • 拆箱过程是通过调用包装类的 xxxValue 方法实现的。(xxx 代表对应的基本数据类型)。

(5)装箱、拆箱的应用场景

  • 含类型为 Object 参数的方法
  • 非泛型的容器
  • == 运算符的两个操作,一个操作数是包装类,另一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)。

(6)装箱、拆箱的应用注意点

  • 装箱操作会创建对象,频繁的装箱操作会造成不必要的内存消耗,影响性能。所以应该尽量避免装箱。
  • 基础数据类型的比较操作使用 ==,包装类的比较操作使用 equals 方法。

参考资料

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-03-10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 深入理解 Java 基本数据类型
    • 数据类型分类
      • 值类型
      • 值类型和引用类型的区别
    • 数据转换
      • 自动转换
      • 强制转换
    • 装箱和拆箱
      • 包装类、装箱、拆箱
      • 自动装箱、自动拆箱
      • 装箱、拆箱的应用和注意点
    • 小结
      • 参考资料
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档