文编|JavaBuild

哈喽,大家好呀!我是JavaBuild,以后可以喊我鸟哥!俺滴座右铭是不在沉默中爆发,就在沉默中灭亡,一起加油学习,珍惜现在来之不易的学习时光吧,等工作之后,你就会发现,想学习真的需要挤时间,厚积薄发啦!

我们知道Java是面向对象的静态型编程语言,在Java的世界里万物皆对象。但我认为是万物皆数据,世界由各种各样数据构建起来,我们通过程序去实现数据的增删改查、转入转出、加减乘除等等,不同语言的实现方式殊途同归。

由此可见,数据对于程序语言的重要性,而在Java中用来规范数据的标准我们将其称之为“数据类型”,这便是我们今天的Topic!

在下图中我们将Java中的数据类型分为三个部分:基本数据类型包装类型引用数据类型

基本数据类型

在Java中“boolean、char、byte、short、int、long、float 和 double”构建起了数据结构的基础,非常重要,也是很多公司面试的高频考点,所以,为了方便记忆,鸟哥整理了一份表格如下:

类型名称 位数 字节 默认值 取值范围 包装类 缓存区间
byte 8 1 0 -128 ~ 127 Byte -128~127
short 16 2 0 -32768 (-2^15) ~ 32767 (2^15-1) Short -128~127
int 32 4 0 -2147483648 ~ 2147483647 Integer -128~127
long 64 8 0L -2^63 ~2^63 - 1 Long -128~127
char 16 2 '\u0000' 0~65535 Character 0 ~127
float 32 4 0f 1.4e-45 ~ 3.4e+38 Float
double 64 8 0d 4.9e-324~1.798e+308 Double
boolean 1 false true(1),false(0) Boolean

字节与位的关系

在计算机的物理存储中,一条电路线被称之为1位,二进制识别中为0(低电平)或1(高电平),英文中用bit表示,而8个bit组成一个字节,英文为Byte

布尔类型的说明

对于 boolean,官方文档未明确定义,它依赖于 JVM 厂商的具体实现。逻辑上理解是占用 1 位,但是实际中会考虑计算机高效存储因素。

基本数据类型之间的转换规则

基本数据类型之间也存在着转换关系,往往发生在表达式计算的过程中,而这种转换根据不同场景分为:自动类型转换&强制类型转换

自动类型转换:Java编译器无需显示处理,一般由等级低的数据类型向等级高的数据类型转换,如int -> long。很明显,int所能存储的数据必定是long的子集,不存在数据丢失问题。

等级由低到高
byte -> short -> int -> long -> float -> double
char -> int -> long -> float -> double
int a = 3;
double b = 1.5;
// 自动类型转换:a 被转换为 double 类型
double result = a * b;
System.out.println("结果: " + result); // 输出:结果: 4.5

强制类型转换:由高等级数据转为低等级数据时往往存在强制类型转换,这时候Java编译器认为存在隐患,需要程序员介入,显示的处理强转,潜在风险是数据丢失或精度丢失。

由左到右需要强转
double -> float -> long -> int -> char -> short -> byte
double c = 10.1;
// 强制类型转换:将 double 类型转换为 int 类型,精度丢失
int d = (int) c;
System.out.println("整数值: " + d); // 输出:整数值: 10

转换规则如下

= 右边先自动转换成表达式中最高级的数据类型,再进行运算。整型经过运算会自动转化最低 int 级别,如两个 char 类型的相加,得到的是一个 int 类型的数值。
= 左边数据类型级别 大于 右边数据类型级别,右边会自动升级
= 左边数据类型级别 小于 右边数据类型级别,需要强制转换右边数据类型
char 与 short,char 与 byte 之间需要强转,因为 char 是无符号类型

包装类型

这八种基本类型都有对应的包装类分别为:Byte、Short、Integer、Long、Float、Double、Character、Boolean 。

因为Java中一切皆对象,基本数据类型无法满足这个大口号,比如泛型、序列化、类型转换、高频数据区间的缓存等,故为了弥补,便诞生了8种基本数据类型对应的包装类型。

包装类型与基本数据类型差异

  • 使用场景: 在Java中除了一些常量和局部变量的定义会用到基础数据类型外,绝大部分情况下均采用包装类型,如方法参数,对象属性等,且基本数据类型不能用于泛型,包装类型可以!
  • 默认值: 包装类型比基本类型多了一个非功能值:null,在不做任何赋值的情况下,包装类型的默认就是null,而基本数据类型都有相应的默认值,见上面表格。
  • 所占内存 因为包装类型是对象,会有一些对象头等信息,所以占用空间上要大于基本数据类型。
  • 比较方式 基本类型采用 == 号比较,比较的是值,而对于包装类型来说,==比较的其实是对象的内存地址,对象值的比较需要通过equals()方法完成。

[注意]: 很多同学都以为基本数据类型存在栈中,包装类型作为对象存储在堆中,这个观点是有失偏颇的,如果基础数据类型的成员变量在没有被static关键字修饰的情况下,是存在的堆中的,只有局部变量被存在栈的局部变量表中!而全部对象都存在堆中,也是个不完整的答案,这里涉及到HotSpot中的逃逸分析,等讲到JVM时再展开说吧。

自动装箱与拆箱

在Java中不仅仅基本类型之间存在着转换,基本数据类型与包装类型之间同样存在着转换,在JDK1.5之前是不支持自动装箱与拆箱的,所以那时候需要通过显示的方法调用来实现转换,而JDK1.5开始,自动化程度提升了。

装箱:基本类型转变为包装器类型的过程。

拆箱:包装器类型转变为基本类型的过程。

//JDK1.5之前是不支持自动装箱和自动拆箱的,定义Integer对象,必须
Integer i = new Integer(8); //JDK1.5开始,提供了自动装箱的功能,定义Integer对象可以这样
Integer i = 8;
int n = i;//自动拆箱

实现原理

装箱是通过调用包装器类的 valueOf 方法实现的
拆箱是通过调用包装器类的 xxxValue 方法实现的,xxx代表对应的基本数据类型。
如int装箱的时候自动调用Integer的valueOf(int)方法;Integer拆箱的时候自动调用Integer的intValue方法。

【需要注意的问题点】:

1、整型的包装类 valueOf 方法返回对象时,在常用的取值范围内,会返回缓存对象。

2、浮点型的包装类 valueOf 方法返回新的对象。

3、布尔型的包装类 valueOf 方法 Boolean类的静态常量 TRUE | FALSE。

Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 200;
Integer i4 = 200; System.out.println(i1 == i2);//true
System.out.println(i3 == i4);//false Double d1 = 100.0;
Double d2 = 100.0;
Double d3 = 200.0;
Double d4 = 200.0;
System.out.println(d1 == d2);//false
System.out.println(d3 == d4);//false Boolean b1 = false;
Boolean b2 = false;
Boolean b3 = true;
Boolean b4 = true;
System.out.println(b1 == b2);//true
System.out.println(b3 == b4);//true

以上代码中,我们已Integer为例展开解释一下,基本数据类型的包装类除了 Float 和 Double 之外,其他六个包装器类(Byte、Short、Integer、Long、Character、Boolean)都有常量缓存池。而Integer的缓存区间是-128~127。

我们去看一下Integer类的缓存源码

public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
private static class IntegerCache {
static final int low = -128;
static final int high;
static {
// high value may be configured by property
int h = 127;
}
}

IntegerCache 这个静态内部类中设置了缓存区间,当我们通过valueOf()方法获取Integer对象时,会先去找该整数是否在缓存池中,有则直接返回,没有则新建并存入缓存池。

这就解释了为什么第一个 == 号结果是true,而第二个为false,因为超出了缓存区间,每次都新建一个对象,而 == 号又是比较对象地址,对于两个不同的对象,地址肯定不一样啦。

引用数据类型

Java的数据类型除了8种基本数据类型和对应的包装类型外,还有一个分类为引用数据类型,在文章开头的树形图中已经分好,引用类型分为:数组,类和接口。

那为什么叫他引用数据类型呢?在创建引用数据类型时,会在栈上给其引用句柄,分配一块内存,然后对象的信息存储在堆上,在程序调用的时候,通过栈上的引用句柄指向堆中的对象,从而获取想要的数据。

因数组,类,接口都包含着太多内容,在后续的博客中会陆续详解,所以本文略做介绍,粗略感受一下。

数组:

int [] arrays = {1,2,3};
System.out.println(arrays);
// 打印结果:[I@2d209079

打印结果中的一串内容,世界上是arrays的对象首地址,要想看到结果,需要调用java.lang.Object 类的 toString() 方法。

类:

public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
}

String是一个类,也是字符串的代表,所以它也是引用数据类型

接口:

List<String> list = new ArrayList<>();
System.out.println(list);

List 是一个非常典型的接口,属于Java的一种集合,存储的元素是有序的、可重复的。

【注意】

1、包装类可以实现基本类型和字符串之间的转换,字符串转基本类型:parseXXX(String s);基本类型转字符串:String.valueOf(基本类型)。
2、引用数据类型的默认值为 null,包括数组和接口。
3、char a = 'h'char :单引号,String a = "hello" :双引号。

春眠不觉晓,Java数据类型知多少?基础牢不牢看完本文就有数了的更多相关文章

  1. 新鲜出炉!JAVA线程池精华篇深度讲解,看完你还怕面试被问到吗?

    前言 前两天趁着假期在整理粉丝私信的时候看到一个粉丝朋友的私信跟我说自己现在正在复习准备面试,自己在复习到线程池这一块的时候有点卡壳,总感觉自己差了点什么.想要我帮他指导一下.这不趁着假期我也有时间我 ...

  2. 深度分析:Java并发编程之线程池技术,看完面试这个再也不慌了!

    线程池的好处 Java中的线程池是运用场景最多的并发框架,几乎所有需要异步或并发执行任务的程序都可以使用线程池.在开发过程中,合理地使用线程池,相对于单线程串行处理(Serial Processing ...

  3. Java基础?看完以后再也不惧怕面试了

    前言 这篇文章主要是Java基础部分,主要分为3个部分:Java集合.Java多线.JVM:这些东西帮助我面试成功率提升了很多.后面还有中间件Spring.Redis.RocketMQ等等吧,祝愿大家 ...

  4. java数据类型转换有哪几种?看这篇就够了!

    前言 在上一篇文章中,壹哥给大家讲解了Java中的数据类型,从此大家就知道了基本类型和引用类型,尤其是8种基本类型的使用和各自特点.但实际上数据类型的使用还有很多更深入的内容,比如java数据类型直接 ...

  5. 图解Java线程的生命周期,看完再也不怕面试官问了

    文章首发自个人微信公众号: 小哈学Java https://www.exception.site/java-concurrency/java-concurrency-thread-life-cycle ...

  6. Java学习之旅基础知识篇:数据类型及流程控制

    经过开篇对Java运行机制及相关环境搭建,本篇主要讨论Java程序开发的基础知识点,我简单的梳理一下.在讲解数据类型之前,我顺便提及一下Java注释:单行注释.多行注释以及文档注释,这里重点强调文档注 ...

  7. Java基础-Java数据类型

    Java基础-Java数据类型 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.数据类型的作用 数据类型就是一组值,以及这一组值上的操作,数据类型可以决定数据的存储方式,取值范围 ...

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

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

  9. Java数据类型基础

    Java 数据类型基础 数据类型 强类型语言 要求变量的使用要严格符合规定,所有变量必须先定义后使用 Java数据分为两大类 基本类型(primitive type) 数值类型 整数类型 byte(1 ...

  10. 回顾java基础—Java数据类型

    1  java数据类型.8种基本类型,3种引用类型 基本类型(也称:原始类型):byte.short.int.long.char.float.double.boolean 引用类型:类,接口,数组 2 ...

随机推荐

  1. 02-Shell变量

    1.Shell变量 1.1 Shell变量的介绍 变量用于存储管理临时的数据, 这些数据都是在运行内存中的. 1.2 变量类型 系统环境变量 自定义变量 特殊符号变量 2.系统环境变量 2.1 介绍 ...

  2. Android Tools Project Site

    Android Tools Project Site Search this site   Projects Overview Screenshots Release Status Roadmap D ...

  3. Jmeter将响应数据的结果保存到本地的一个文件(xls和csv)

    打印excel和csv文件的区别?? 第一种:打印excel 第二种:打印csv文件 创建beanshell后置处理器  import org.json.*;import java.io.*; Str ...

  4. 2023_10_10_MYSQL_DAY_02_课后题

    2023_10_10_MYSQL_DAY_02_课后题 #06章1--7题 #1. 查询10号部门所有员工的员工姓名,员工工资,工资级别. SELECT e.ename 员工姓名,e.`sal` 员工 ...

  5. ndk开发之native层访问java层

    一.native层访问java层的成员变量 java层的成员变量可以分为实例变量和静态变量,不过他们的访问方法比较类似,可以分为以下三步: 获取java类对应的jclass对象 获取需要访问的成员变量 ...

  6. 文心一言 VS 讯飞星火 VS chatgpt (111)-- 算法导论10.2 2题

    二.用go语言,用一个单链表 L实现一个栈.要求操作 PUSH和 POP 的运行时间仍为 O(1). 文心一言: 在 Go 语言中,我们可以用结构体来实现一个单链表,然后再用栈的相关操作. 以下是一个 ...

  7. Linux-管道、环境变量、常用命令

    目录 管道 概念 要点 与文件重定向的区别 环境变量 概念 查看 常用命令 查看系统状况 权限 文件查找 用户相关 工具 管道 概念 管道的作用类似于文件重定向,可以将前一个命令的stout做为下一个 ...

  8. 通过.NET Core CLI 来创建并运行ASP.NET CORE应用程序

    说明: .NET Core 命令行接口 (CLI) 工具是用于开发.生成.运行和发布 .NET Core 应用程序的跨平台工具链. .NET Core CLI 包含在 .NET Core SDK 中. ...

  9. 解决IDEA中.properties文件中文变问号(???)的问题(已解决)

    问题背景 构建SpringBoot项目时,项目结构中有一个application.properties文件.这个项目是Spring Boot一个特有的配置文件.内容如下(我写了一些日志的配置): 写到 ...

  10. 从GPT定制到Turbo升级再到Assistants API,未来AI世界,你准备好了吗?

    引言 在OpenAI DevDay发布会上,OpenAI再次震撼整个人工智能行业,为AI领域带来了重大的更新.CEO Sam Altman宣布推出了定制版本的ChatGPT,这意味着用户现在可以根据自 ...