老王的JAVA基础课:第6课 JAVA基本数据类型

2024-06-12 11:18

本文主要是介绍老王的JAVA基础课:第6课 JAVA基本数据类型,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述

什么是基本数据类型

这节课我们来学习java的基本数据类型,首先来看Q&A:
Q: 何谓数据类型?
A: 程序的本质是处理各种数据,在计算机底层来讲数据本身没有类型。而数据类型则表示一个数据是以什么类型来表示。
Q: 何谓基本?
A: java中最基础的数据类型,存在于栈内存(死记硬背,以后会讲含义)。仅包含数据,可直接使用。与之相对的为引用类型(以后会讲到)。

JAVA基本数据类型

计算机中数据的最小单位是比特(bit),由于计算机系统的电路设计它只能表示为0或1,8个比特位组成一个字节(byte),byte是数据存储的最小单位。以下是java中基本数据类型以及各类型取值范围。

数据类型类型区分占用空间默认值取值范围
byte整形1字节0-2^7 ~ 2^7-1
short整形2字节0-2^15 ~ 2^15-1
int整形4字节0-2^31 ~ 2^31-1
long整形8字节0L-2^63 ~ 2^63-1
float浮点型4字节0.0F3.4e+38 ~ 1.4e-45
double浮点型8字节0.0D1.8e+308 ~ 4.9e-324
char字符型2字节00 ~ 2^16-1
boolean布尔型1字节falsetrue/false

以上内容非常简单,前三列记住即可。你可能疑惑为什么取值范围都是乱七八糟的。现在来学习为什么取值范围都不是我们预料的整数。

整形数据在内存中的表示

我们前面提到byte是数据存储的最小单位,而byte作为基本数据类型的一种,它的长度就是1byte,而1byte=8bit。以byte为例,byte在内存中表示如下:
在这里插入图片描述
整形数据的最高位为符号位,0表示正数,1表示负数。后面的bit为数据位,byte可以表示7个数据位长度的数据。那么7个数据位可以表示的正数范围如下:
在这里插入图片描述
我们知道1bit最大只能表示1,那么2bit最大可以表示2^1+1 = 3,以此类推7位可表示的最大值为上图中依次相加,就等于2^7-1,也即十进制的127。在计算机中,数据的表示都是以“补码”展现,正数的补码是其本身(本身又叫“原码”),而负数的补码需要将原码除符号位之外的每一位取反(0变成1,1变成0)后得到反码,然后加1,略微复杂。初学可能不太好理解,在后续的课程中会推出专门的课题来介绍原码、补码、以及反码。

由以上得知负数的补码为原码除符号位外按位取反后+1,我们来看byte1类型的-1在内存中是如何表示的:在这里插入图片描述
因为负数的符号位为1,所以-1的原码为10000001,符号位不变,其他位取反得到反码11111110,而补码为反码+1,那么-1的补码表示11111111。大家可能会注意到整形数据的最大值和最小值的绝对值并不是一样的,例如byte的最大值为127,而最小值为-128,这是怎么做到的呢?

注意到+0表示为00000000,而-0可以表示为10000000。但在现实中+0与-0都是表示0。为了不必要的浪费。在计算机系统中,10000000表示为最小值,如果是byte那么最小值就表示为-128.

由此我们可以推演到short、int、long都是如此。

float与double类型

float为单精度浮点型数据类型,double为双精度浮点型数据类型。这两种类型都可以表示小数,实际上只有精度和取值范围区别。切记不可用于货币等关键数据的处理,因为浮点型数据无法表示准确地表示一个小数(同样以后再讲)。float的默认值为0.0f,而double的默认值为0.0d。注意最后的f和d。示例:

float data1 = 1.2f;
double data2 = 2.34d;

char类型

char类型是一个单一的 16 位 Unicode 字符,注意其不存在符号位(最高位也是数据位),所以其范围为0~2^16-1(65535)。char可以存储任何字符,注意其存储的是字符数据而非整形数据。假如我们以如下方式赋值,输出结果并不是想当然的65,如下:

char c = 65;
System.out.println(c);-----------输出结果-------------
A

这是因为65在Unicode中表示A这个字符,如果我们想赋值A到char c,我们可以使用单引号括起来。

char c = 'A';
System.out.println(c);-----------输出结果-------------
A

boolean类型

在Java中所有基本类型都有一个与之对应的类。比如int类型对应Integer类,double类型对应Double类。这些类被称为包装器类(wrapper)。Java有8种基本类型,有9个包装器,分别为:Intger、Long、Short、Byte、Double、Float、Character、Boolean以及Void。

那么问题又来了,为什么需要包装器类型?我们知道基本数据类型仅包含了数据,在实际开发中其他系统可能传入一个数值过来,如果使用基本数据类型我们无从判断这个值是否存在。这个时候必须要用到包装器类型,因为包装器类型允许值为null,可以通过值是否为null来判断这个值是否真实存在。另外包装器类型提供了许多便捷的方法,避免我们重复造轮子。

以下是各数据类型的基础示例:

public class TestDataType {public static void main(String[] args) {// byteSystem.out.println("基本数据类型byte 所占bit数:" + Byte.SIZE);System.out.println("byte的包装器类型为:java.lang.Byte");System.out.println("最小值:" + Byte.MIN_VALUE);System.out.println("最大值:" + Byte.MAX_VALUE);System.out.println("-------------------------------------------");// shortSystem.out.println("基本数据类型short 所占bit数:" + Short.SIZE);System.out.println("short的包装器类型为:java.lang.Short");System.out.println("最小值:" + Short.MIN_VALUE);System.out.println("最大值:" + Short.MAX_VALUE);System.out.println("-------------------------------------------");// intSystem.out.println("基本数据类型int 所占bit数:" + Integer.SIZE);System.out.println("int的包装器类型为:java.lang.Integer");System.out.println("最小值:" + Integer.MIN_VALUE);System.out.println("最大值:" + Integer.MAX_VALUE);System.out.println("-------------------------------------------");// longSystem.out.println("基本数据类型long 所占bit数:" + Long.SIZE);System.out.println("long的包装器类型为:java.lang.Long");System.out.println("最小值:" + Long.MIN_VALUE);System.out.println("最大值:" + Long.MAX_VALUE);System.out.println("-------------------------------------------");// floatSystem.out.println("基本数据类型float 所占bit数:" + Float.SIZE);System.out.println("float的包装器类型为:java.lang.Float");System.out.println("最小值:" + Float.MIN_VALUE);System.out.println("最大值:" + Float.MAX_VALUE);System.out.println("-------------------------------------------");// doubleSystem.out.println("基本数据类型double 所占bit数:" + Double.SIZE);System.out.println("double的包装器类型为:java.lang.Double");System.out.println("最小值:" + Double.MIN_VALUE);System.out.println("最大值:" + Double.MAX_VALUE);System.out.println("-------------------------------------------");// charSystem.out.println("基本数据类型char 所占bit数:" + Character.SIZE);System.out.println("char的包装器类型为:java.lang.Character");// 以数值形式输出System.out.println("最小值:" + (int) Character.MIN_VALUE);System.out.println("最大值:" + (int) Character.MAX_VALUE);}
}

编译执行后输出:

基本数据类型byte 所占bit数:8
byte的包装器类型为:java.lang.Byte
最小值:-128
最大值:127
-------------------------------------------
基本数据类型short 所占bit数:16
short的包装器类型为:java.lang.Short
最小值:-32768
最大值:32767
-------------------------------------------
基本数据类型int 所占bit数:32
int的包装器类型为:java.lang.Integer
最小值:-2147483648
最大值:2147483647
-------------------------------------------
基本数据类型long 所占bit数:64
long的包装器类型为:java.lang.Long
最小值:-9223372036854775808
最大值:9223372036854775807
-------------------------------------------
基本数据类型float 所占bit数:32
float的包装器类型为:java.lang.Float
最小值:1.4E-45
最大值:3.4028235E38
-------------------------------------------
基本数据类型double 所占bit数:64
double的包装器类型为:java.lang.Double
最小值:4.9E-324
最大值:1.7976931348623157E308
-------------------------------------------
基本数据类型char 所占bit数:16
char的包装器类型为:java.lang.Character
最小值:0
最大值:65535

数值在不同进制下的表示

Java支持二进制,八进制,十进制,十六进制的数值表示,我们可以以如下方式定义一个整形数值:

//二进制,以0b或0B开头
int binary = 0b100;
//八进制,以0开头
int octal = 0100;
//十进制,无特殊写法
int decimal = 100;
//十六进制,以0x或0X开头
int hex = 0x100;
System.out.println("二进制下100的十进制表示:" + binary);
System.out.println("八进制下100的十进制表示:" + octal);
System.out.println("十进制下100的十进制表示:" + decimal);
System.out.println("十六进制下100的十进制表示:" + hex);

以上代码编译输出结果:

二进制下100的十进制表示:4
八进制下100的十进制表示:64
十进制下100的十进制表示:100
十六进制下100的十进制表示:256

类型转换

假如需要将一个long类型数据转化为int,或将byte类型数据转为int。就需要类型转换,类型转换分为自动类型转换强制类型转换两种。

1. 自动类型转换

将占内存空间小的类型转换为占内存空间大的类型时,不存在转换风险,java会替我们完成自动类型转换。示例:

int a = 1;
long b = a;

以上代码可以编译通过,因为int为4字节而long为8字节。如果颠倒顺序编译器将不会通过编译,示例:

long a = 1;
int b = a; //无法通过编译
2. 强制类型转换

既然java不会自动将长类型转化为短类型,我们有没有办法强行转为短类型呢?答案是有的。可以使用如下写法:

long a = 1;
int b = (int)a; //编译通过
3. 为什么java不自动转化所有类型?

因为将长类型转化为短类型有潜在风险,如果不小心将一个int a = 10000赋值给byte b而编译器又放行的话,这将很有可能带来严重问题。而java还是赋予了程序员显式转换的能力,但是在强制转换前一定要清楚地了解转换的风险。

灵魂拷问:将int a = 10000赋值给byte b = (byte) a,那么b是多少?

我们知道强制类型转换的潜在风险是精度丢失,那么究竟丢失了多少呢?我们来分析一下
a为int类型占4字节,在内存中表示如下:
00000000 00000000 00100111 00010000
而byte为1个字节,java类型强制转换实际上是丢弃多余的bit,可以理解为截断超过需要被赋值的类型的长度。现在很容易得到byte b在内存中表示如下:
00010000
以十进制表示,b的值为16。我们来执行一下以上代码:

public static void main(String[] args) {int a = 10000;byte b = (byte) a;System.out.println(b);
}

编译运行输出结果:16
与我们预料的没差,验证了我们前面的猜测。

总结

这节课我们学习了java基本数据类型的相关知识,着手多练习有助于快速提高哦,下一节我们将学习变量类型。

目录

老王的JAVA基础课:序言
老王的JAVA基础课:第1课 计算机基础知识
老王的JAVA基础课:第2课 JDK安装和环境变量配置
老王的JAVA基础课:第3课 IDEA的安装和使用
老王的JAVA基础课:第4课 以hello world学习基础语法
老王的JAVA基础课:第5课 面向对象

其他文章

2020年高效搬砖必备的IDEA插件(附安装包)
详解从p12证书提取RSA公私钥和序列号(小白向)

本教程同时发布在我的公众号:Java学步园,欢迎加入JAVA初级交流群:757443185,滑到最上面左侧扫描二维码哦~

这篇关于老王的JAVA基础课:第6课 JAVA基本数据类型的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1054062

相关文章

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

Spring AI集成DeepSeek的详细步骤

《SpringAI集成DeepSeek的详细步骤》DeepSeek作为一款卓越的国产AI模型,越来越多的公司考虑在自己的应用中集成,对于Java应用来说,我们可以借助SpringAI集成DeepSe... 目录DeepSeek 介绍Spring AI 是什么?1、环境准备2、构建项目2.1、pom依赖2.2