Java-数据类型

java是强类型语言:要求变量的使用必须要严格符合规定,所有变量都必须先定义后才能使用。

在java里,数据类型分为两大类:基本数据类型和引用数据类型。

基本数据类型用于存储简单的数值。它们直接存储数据值,效率非常高。这 8 种类型可以分为四组:

整数类型

浮点类型

字符类型

布尔类型

1.整数类型

用来存储不带小数的数据。

类型 占用内存 取值范围 默认值 说明
byte 1 字节 -128 ~ 127 0 适合存储状态码或者小整数
short 2 字节 -32,768 ~ 32,767 0 较少使用
int 4 字节 约 -21亿 ~ 21亿 0 最常使用
long 8 字节 范围极大 0L 存储超大整数(如时间戳),赋值时必须加 L 后缀

测试:

java 复制代码
        byte a = 1;
        System.out.println(a+1);
        short b = 2;
        System.out.println(b+1);
        int c = 3;
        System.out.println(c+1);
        long d = 4;
        System.out.println(d+1);

结果:

2.浮点类型

用来存储带小数的数据。

类型 占用内存 精度 默认值 说明
float 4 字节 约 6~7 位有效数字 0.0f 单精度,赋值时必须加 F 后缀
double 8 字节 约 15~16 位有效数字 0.0d 最常用的小数类型,是 Java 默认的小数类型

测试:注意(使用小数但是不加f,默认是double类型)。

java 复制代码
        float a = 0.6f;
        System.out.println( a+0.1);
        
        double b = 0.6;
        System.out.println( b+0.1);
        
        float c = 0.6f;
        System.out.println(c==0.6);

结果:

可以看到,这里对float的计算出现误差了,这是为什么?

在进行小数的加减乘除运算时,会有精度损失,因为计算机不管在运算还是存储,都会转为二进制操作,假设有一个10进制的数字69.875,整数部分的二进制为0100 0101,小数部分的二进制为111,如果是10进制的0.9,小数部分的二进制为1110011000110011001100110011001100110011001101,一共45位表示,如果是0.226,小数部分就更长了,有55位。而在java中,而不论是float和double,在底层占用的字节数是有限的,float占4个字节,32个bit位,double8个字节,64个bit位,而给小数部分的bit位数,float是23位,double是52位,多出来的会被舍弃。小数在存储的时候有可能是不精确的,计算出来的结果也可能是不精确的。

为什么double看起来没问题?

那是因为double 有 64 位空间,比 float 多了一倍的精度。它在存储 0.6 和 0.1 时,保留了更多的小数位,误差极小极小。

实际上如果用高精度的工具去检查,double 计算出的 0.6 + 0.1 的真实结果其实也是存在误差的。

Java 的 System.out.println 在打印 double 时,会默认做一个"智能美化"。如果误差非常小(超出了日常使用的精度),它会直接四舍五入显示为 0.7,为了让你看着舒服。

也可以验证:

java 复制代码
        double b = 0.6 ;
        // 使用 BigDecimal 的 valueOf 可以看到 double 的真实值
        System.out.println(new BigDecimal(b+0.1));

结果:

所以尽量不要使用浮点数进行比较,最好使用BigDecimal。这里暂时不介绍BigDecimal了。

3.字符类型

类型: char。

占用内存: 2 字节。

取值范围: Unicode 字符 (0 ~ 65535)。

默认值: '\u0000'。

说明: 用于存储单个字符,必须使用单引号括起来。它可以存储英文字母、数字、汉字等,例如 char grade = 'A';char ch = '中';

测试:

java 复制代码
        char a = 1;
        System.out.println(a);

        char b = '1';
        System.out.println(b);

结果:

为什么两者的结果不一样?这就涉及到char的原理了。

当不加引号的时候:

1 是 ASCII 码值(Unicode 编码)。

Java 会查找 ASCII/Unicode 表中编号为 1 的字符,ASCII 码 1 对应的是 是一个控制字符,不可显示,所以你会看到空白或者特殊符号。

当加引号的时候:

char 类型有两个视角:

存储时:存的是数字(ASCII/Unicode 编码值)。

输出时:显示的是字符(人类可读的形式)。

在赋值阶段:

'1' → 编译器查找 ASCII 表 → 发现 '1' 对应的编码是 49

→ 在内存中存储 49

在输出阶段:

System.out.println(b) 看到 b 是 char 类型

→ 从内存读取 49

→ 查 ASCII 表反向转换:49 → '1'

→ 在屏幕上显示字符 '1'

所以,在 Java中,char 类型底层存储的其实是一个整数。

  • 存储空间:Java 中的 char 占用 2个字节(16位)。
  • 编码方式:它使用 Unicode 编码(兼容 ASCII)。
  • 映射关系:每一个字符都对应一个唯一的数字。

你可以把 char 想象成一个"翻译官":

  • 当你写 char a = 1; 时,你直接给了它数字 1,它就去查"1号"对应的符号,结果查到了不可见的控制符。
  • 当你写 char b = '1'; 时,你告诉它"我要字符1",它就去查"字符1"的编号(49),然后存下了 49。

4.布尔类型

类型: boolean

取值: 只有 truefalse 两个值。

默认值: false

说明: 用于逻辑判断。Java 中的 boolean 类型不能与数字(如 0 或 1)互相转换。

验证boolean类型不能直接和0或1转换:

5.类型转换

由于java是强类型语言,所以要进行有些运算的时候,需要用到类型转换。

低------------------------------------------------------>高

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

运算中,不同类型的数据先转换为同一类型,然后再进行运算。

强制转换 : 取值范围大的数值转换为取值范围小的数值。其语法为:(类型)变量名

自由转换(隐式转换):取值范围小的数值转换为取值范围大的数值。

转换规则1:取值范围小的,和取值范围大的进行运算,小的会先提升为大的,再进行运算。

转换规则2:byte,short,char三种类型的数据再运算的时候,都会直接先提升为int,然后再进行运算。

比如:

long转int需要强转。

细节1:

在操作比较大的数字的时候,注意栈溢出:

java 复制代码
        // JDK7新特性,数字之间可以用下划线分割
        int money = 10_0000_0000;

        int years = 20;

        int total = money * years; //-1474836480,计算的时候溢出了
        System.out.println(total);

        long total2 = money * years; //默认是int,转换之前已经存在问题了
        System.out.println(total2);

         long total3 = money*((long) years); //先把一个数转换为Long

        System.out.println(total3);

结果:

细节2:

java 复制代码
        short s = 1;

        s += 1;
        System.out.println(s); // 2

把左边和右边的值进行相加,得到结果2,再赋值给左边的变量,等同于s = s+1;

问题是short类型和int类型进行运算时,short会先转换int型,所以计算得出的结果为int型,但左边的变量s为short,正常int不能转换为short,为什么不报错?

因为+=,-=,*=,/=,%=都隐藏了一个强制类型转换,上面的s+=1就等于s = (short)(s+1)

6.引用数据类型

引用数据类型比基本数据类型更复杂,它们存储的是对象在内存中的地址(引用),而不是数据本身。

常见类型: 类(如 String)、接口(如 List)、数组(如 int[])等。

默认值: null

这里不花过多时间介绍了。

相关推荐
学习3人组1 小时前
Mes全连路架构图
java·erp
上弦月-编程1 小时前
C语言指针从入门到实战
java·jvm·算法
Cyan_RA91 小时前
SpringMVC 请求数据绑定与参数映射 详解
java·后端·spring·mvc·springmvc·映射请求数据
逻辑驱动的ken2 小时前
Java高频面试考点场景题20
java·开发语言·深度学习·面试·职场和发展
bzmK1DTbd2 小时前
Java游戏服务器:Netty框架的高并发网络通信
java·服务器·游戏
longxibo2 小时前
【Flowable 7.2 源码深度解析与实战-前言】
java·后端·流程图
小龙报2 小时前
【Coze-AI智能体平台】低代码省时高效:Coze 应用开发全流程指南
java·人工智能·python·深度学习·低代码·chatgpt·交互
勿忘初心12212 小时前
【Java实战】SpringBoot 集成 freemarker 导出 Word 模板
java·spring boot·freemarker·模板引擎·word导出·后端实战
绿草在线2 小时前
SpringBoot项目实战:从零搭建高效开发环境
java·spring boot·后端