阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

变量和数据类型

589次阅读
没有评论

共计 5219 个字符,预计需要花费 14 分钟才能阅读完成。

变量

什么是变量?

变量就是初中数学的代数的概念,例如一个简单的方程,x,y 都是变量:

在 Java 中,变量分为两种:基本类型的变量和引用类型的变量。

我们先讨论基本类型的变量。

在 Java 中,变量必须先定义后使用,在定义变量的时候,可以给它一个初始值。例如:

int x = 1;

上述语句定义了一个整型 int 类型的变量,名称为x,初始值为1

不写初始值,就相当于给它指定了默认值。默认值总是0

来看一个完整的定义变量,然后打印变量值的例子:

// 定义并打印变量
public class Main {public static void main(String[] args) {int x = 100; // 定义 int 类型变量 x,并赋予初始值 100
        System.out.println(x); // 打印该变量的值
    }
}

变量的一个重要特点是可以重新赋值。例如,对变量x,先赋值100,再赋值200,观察两次打印的结果:

// 重新赋值变量
public class Main {public static void main(String[] args) {int x = 100; // 定义 int 类型变量 x,并赋予初始值 100
        System.out.println(x); // 打印该变量的值,观察是否为 100
        x = 200; // 重新赋值为 200
        System.out.println(x); // 打印该变量的值,观察是否为 200
    }
}

注意到第一次定义变量 x 的时候,需要指定变量类型 int,因此使用语句int x = 100;。而第二次重新赋值的时候,变量x 已经存在了,不能再重复定义,因此不能指定变量类型int,必须使用语句x = 200;

变量不但可以重新赋值,还可以赋值给其他变量。让我们来看一个例子:

// 变量之间的赋值
public class Main {public static void main(String[] args) {int n = 100; // 定义变量 n,同时赋值为 100
        System.out.println("n =" + n); // 打印 n 的值

        n = 200; // 变量 n 赋值为 200
        System.out.println("n =" + n); // 打印 n 的值

        int x = n; // 变量 x 赋值为 n(n 的值为 200,因此赋值后 x 的值也是 200)
        System.out.println("x =" + x); // 打印 x 的值

        x = x + 100; // 变量 x 赋值为 x +100(x 的值为 200,因此赋值后 x 的值是 200+100=300)
        System.out.println("x =" + x); // 打印 x 的值
        System.out.println("n =" + n); // 再次打印 n 的值,n 应该是 200 还是 300?
   }
}

我们一行一行地分析代码执行流程:

执行 int n = 100;,该语句定义了变量n,同时赋值为100,因此,JVM 在内存中为变量n 分配一个“存储单元”,填入值100

      n
      │
      ▼
┌───┬───┬───┬───┬───┬───┬───┐
│   │100│   │   │   │   │   │
└───┴───┴───┴───┴───┴───┴───┘

执行 n = 200; 时,JVM 把 200 写入变量 n 的存储单元,因此,原有的值被覆盖,现在 n 的值为200

      n
      │
      ▼
┌───┬───┬───┬───┬───┬───┬───┐
│   │200│   │   │   │   │   │
└───┴───┴───┴───┴───┴───┴───┘

执行 int x = n; 时,定义了一个新的变量 x,同时对x 赋值,因此,JVM 需要 新分配 一个存储单元给变量 x,并写入和变量n 一样的值,结果是变量 x 的值也变为200

      n           x
      │           │
      ▼           ▼
┌───┬───┬───┬───┬───┬───┬───┐
│   │200│   │   │200│   │   │
└───┴───┴───┴───┴───┴───┴───┘

执行 x = x + 100; 时,JVM 首先计算等式右边的值 x + 100,结果为300(因为此刻x 的值为 200),然后,将结果300 写入 x 的存储单元,因此,变量 x 最终的值变为300

      n           x
      │           │
      ▼           ▼
┌───┬───┬───┬───┬───┬───┬───┐
│   │200│   │   │300│   │   │
└───┴───┴───┴───┴───┴───┴───┘

可见,变量可以反复赋值。注意,等号 = 是赋值语句,不是数学意义上的相等,否则无法解释x = x + 100

基本数据类型

基本数据类型是 CPU 可以直接进行运算的类型。Java 定义了以下几种基本数据类型:

  • 整数类型:byte,short,int,long
  • 浮点数类型:float,double
  • 字符类型:char
  • 布尔类型:boolean

Java 定义的这些基本数据类型有什么区别呢?要了解这些区别,我们就必须简单了解一下计算机内存的基本结构。

计算机内存的最小存储单元是字节(byte),一个字节就是一个 8 位二进制数,即 8 个 bit。它的二进制表示范围从00000000~11111111,换算成十进制是 0~255,换算成十六进制是00~ff

内存单元从 0 开始编号,称为内存地址。每个内存单元可以看作一间房间,内存地址就是门牌号。

  0   1   2   3   4   5   6  ...
┌───┬───┬───┬───┬───┬───┬───┐
│   │   │   │   │   │   │   │...
└───┴───┴───┴───┴───┴───┴───┘

一个字节是 1byte,1024 字节是 1K,1024K 是 1M,1024M 是 1G,1024G 是 1T。一个拥有 4T 内存的计算机的字节数量就是:

4T = 4 x 1024G
   = 4 x 1024 x 1024M
   = 4 x 1024 x 1024 x 1024K
   = 4 x 1024 x 1024 x 1024 x 1024
   = 4398046511104

不同的数据类型占用的字节数不一样。我们看一下 Java 基本数据类型占用的字节数:

       ┌───┐
  byte │   │
       └───┘
       ┌───┬───┐
 short │   │   │
       └───┴───┘
       ┌───┬───┬───┬───┐
   int │   │   │   │   │
       └───┴───┴───┴───┘
       ┌───┬───┬───┬───┬───┬───┬───┬───┐
  long │   │   │   │   │   │   │   │   │
       └───┴───┴───┴───┴───┴───┴───┴───┘
       ┌───┬───┬───┬───┐
 float │   │   │   │   │
       └───┴───┴───┴───┘
       ┌───┬───┬───┬───┬───┬───┬───┬───┐
double │   │   │   │   │   │   │   │   │
       └───┴───┴───┴───┴───┴───┴───┴───┘
       ┌───┬───┐
  char │   │   │
       └───┴───┘

byte恰好就是一个字节,而 longdouble需要 8 个字节。

整型

对于整型类型,Java 只定义了带符号的整型,因此,最高位的 bit 表示符号位(0 表示正数,1 表示负数)。各种整型能表示的最大范围如下:

  • byte:-128 ~ 127
  • short: -32768 ~ 32767
  • int: -2147483648 ~ 2147483647
  • long: -9223372036854775808 ~ 9223372036854775807

我们来看定义整型的例子:

// 定义整型
public class Main {public static void main(String[] args) {int i = 2147483647;
        int i2 = -2147483648;
        int i3 = 2_000_000_000; // 加下划线更容易识别
        int i4 = 0xff0000; // 十六进制表示的 16711680
        int i5 = 0b1000000000; // 二进制表示的 512

        long n1 = 9000000000000000000L; // long 型的结尾需要加 L 
        long n2 = 900; // 没有加 L,此处 900 为 int,但 int 类型可以赋值给 long
        int i6 = 900L; // 错误:不能把 long 型赋值给 int
    }
}

特别注意:同一个数的不同进制的表示是完全相同的,例如15=0xf=0b1111

浮点型

浮点类型的数就是小数,因为小数用科学计数法表示的时候,小数点是可以“浮动”的,如 1234.5 可以表示成 12.345×102,也可以表示成 1.2345×103,所以称为浮点数。

下面是定义浮点数的例子:

float f1 = 3.14f;
float f2 = 3.14e38f; // 科学计数法表示的 3.14x10^38
float f3 = 1.0; // 错误:不带 f 结尾的是 double 类型,不能赋值给 float

double d = 1.79e308;
double d2 = -1.79e308;
double d3 = 4.9e-324; // 科学计数法表示的 4.9x10^-324

对于 float 类型,需要加上 f 后缀。

浮点数可表示的范围非常大,float类型可最大表示 3.4×1038,而 double 类型可最大表示 1.79×10308

布尔类型

布尔类型 boolean 只有 truefalse两个值,布尔类型总是关系运算的计算结果:

boolean b1 = true;
boolean b2 = false;
boolean isGreater = 5 > 3; // 计算结果为 true
int age = 12;
boolean isAdult = age >= 18; // 计算结果为 false

Java 语言对布尔类型的存储并没有做规定,因为理论上存储布尔类型只需要 1 bit,但是通常 JVM 内部会把 boolean 表示为 4 字节整数。

字符类型

字符类型 char 表示一个字符。Java 的 char 类型除了可表示标准的 ASCII 外,还可以表示一个 Unicode 字符:

// 字符类型
public class Main {public static void main(String[] args) {char a = 'A';
        char zh = '中';
        System.out.println(a);
        System.out.println(zh);
    }
}

注意 char 类型使用单引号 ',且仅有一个字符,要和双引号" 的字符串类型区分开。

引用类型

除了上述基本类型的变量,剩下的都是引用类型。例如,引用类型最常用的就是 String 字符串:

String s = "hello";

引用类型的变量类似于 C 语言的指针,它内部存储一个“地址”,指向某个对象在内存的位置,后续我们介绍类的概念时会详细讨论。

常量

定义变量的时候,如果加上 final 修饰符,这个变量就变成了常量:

final double PI = 3.14; // PI 是一个常量
double r = 5.0;
double area = PI * r * r;
PI = 300; // compile error!

常量在定义时进行初始化后就不可再次赋值,再次赋值会导致编译错误。

常量的作用是用有意义的变量名来避免魔术数字(Magic number),例如,不要在代码中到处写3.14,而是定义一个常量。如果将来需要提高计算精度,我们只需要在常量的定义处修改,例如,改成3.1416,而不必在所有地方替换3.14

为了和变量区分开来,根据习惯,常量名通常 全部大写

var 关键字

有些时候,类型的名字太长,写起来比较麻烦。例如:

StringBuilder sb = new StringBuilder();

这个时候,如果想省略变量类型,可以使用 var 关键字:

var sb = new StringBuilder();

编译器会根据赋值语句自动推断出变量 sb 的类型是StringBuilder。对编译器来说,语句:

var sb = new StringBuilder();

实际上会自动变成:

StringBuilder sb = new StringBuilder();

因此,使用 var 定义变量,仅仅是少写了变量类型而已。

变量的作用范围

在 Java 中,多行语句用 {...} 括起来。很多控制语句,例如条件判断和循环,都以 {...} 作为它们自身的范围,例如:

if (...) {// if 开始
    ...
    while (...) {// while 开始
        ...
        if (...) {// if 开始
            ...
        } // if 结束
        ...
    } // while 结束
    ...
} // if 结束

只要正确地嵌套这些{...},编译器就能识别出语句块的开始和结束。而在语句块中定义的变量,它有一个作用域,就是从定义处开始,到语句块结束。超出了作用域引用这些变量,编译器会报错。举个例子:

{
    ...
    int i = 0; // 变量 i 从这里开始定义
    ...
    {
        ...
        int x = 1; // 变量 x 从这里开始定义
        ...
        {
            ...
            String s = "hello"; // 变量 s 从这里开始定义
            ...
        } // 变量 s 作用域到此结束
        ...
        // 注意,这是一个新的变量 s,它和上面的变量同名,
        // 但是因为作用域不同,它们是两个不同的变量:
        String s = "hi";
        ...
    } // 变量 x 和 s 作用域到此结束
    ...
} // 变量 i 作用域到此结束

定义变量时,要遵循作用域最小化原则,尽量将变量定义在尽可能小的作用域,并且,不要重复使用变量名。

小结

Java 提供了两种变量类型:基本类型和引用类型

基本类型包括整型,浮点型,布尔型,字符型。

变量可重新赋值,等号是赋值语句,不是数学意义的等号。

常量在初始化后不可重新赋值,使用常量便于理解程序意图。

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-08-05发表,共计5219字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19351
评论数
4
阅读量
7994398
文章搜索
热门文章
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...
再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...
飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛 NAS 中安装 Navidrome 音乐文件中文标签乱码问题解决、安装 FntermX 终端 问题背景 ...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
还在找免费服务器?无广告免费主机,新手也能轻松上手!

还在找免费服务器?无广告免费主机,新手也能轻松上手!

还在找免费服务器?无广告免费主机,新手也能轻松上手! 前言 对于个人开发者、建站新手或是想搭建测试站点的从业者...
仅2MB大小!开源硬件监控工具:Win11 无缝适配,CPU、GPU、网速全维度掌控

仅2MB大小!开源硬件监控工具:Win11 无缝适配,CPU、GPU、网速全维度掌控

还在忍受动辄数百兆的“全家桶”监控软件?后台偷占资源、界面杂乱冗余,想查个 CPU 温度都要层层点选? 今天给...
【开源神器】微信公众号内容单篇、批量下载软件

【开源神器】微信公众号内容单篇、批量下载软件

【开源神器】微信公众号内容单篇、批量下载软件 大家好,我是星哥,很多人都希望能高效地保存微信公众号的文章,用于...
星哥带你玩飞牛NAS-4:飞牛NAS安装istore旁路由,家庭网络升级的最佳实践

星哥带你玩飞牛NAS-4:飞牛NAS安装istore旁路由,家庭网络升级的最佳实践

星哥带你玩飞牛 NAS-4:飞牛 NAS 安装 istore 旁路由,家庭网络升级的最佳实践 开始 大家好我是...
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
300元就能买到的”小钢炮”?惠普7L四盘位小主机解析

300元就能买到的”小钢炮”?惠普7L四盘位小主机解析

  300 元就能买到的 ” 小钢炮 ”?惠普 7L 四盘位小主机解析 最近...
把小米云笔记搬回家:飞牛 NAS 一键部署,小米云笔记自动同步到本地

把小米云笔记搬回家:飞牛 NAS 一键部署,小米云笔记自动同步到本地

把小米云笔记搬回家:飞牛 NAS 一键部署,小米云笔记自动同步到本地 大家好,我是星哥,今天教大家在飞牛 NA...
240 元左右!五盘位 NAS主机,7 代U硬解4K稳如狗,拓展性碾压同价位

240 元左右!五盘位 NAS主机,7 代U硬解4K稳如狗,拓展性碾压同价位

  240 元左右!五盘位 NAS 主机,7 代 U 硬解 4K 稳如狗,拓展性碾压同价位 在 NA...
星哥带你玩飞牛NAS硬件02:某鱼6张左右就可拿下5盘位的飞牛圣体NAS

星哥带你玩飞牛NAS硬件02:某鱼6张左右就可拿下5盘位的飞牛圣体NAS

星哥带你玩飞牛 NAS 硬件 02:某鱼 6 张左右就可拿下 5 盘位的飞牛圣体 NAS 前言 大家好,我是星...
零成本上线!用 Hugging Face免费服务器+Docker 快速部署HertzBeat 监控平台

零成本上线!用 Hugging Face免费服务器+Docker 快速部署HertzBeat 监控平台

零成本上线!用 Hugging Face 免费服务器 +Docker 快速部署 HertzBeat 监控平台 ...