如果编写一个求绝对值的程序,开发者可以把程序设计为由用户从控制台上任意输入一个数字,然后计算这个数字的绝对值并输出到控制台上。为了完成这个操作,需要先向计算机申请一块内存空间用来保存用户所输入的数字。专业上把这块内存空间称为“变量”。之所以称它为“变量”,就是因为这块内存空间中所保存的数据不是固定的,它可以发生改变,因此称为“变量”。同时,为了方便使用变量,还需要给每个变量起一个名字,这个名字叫做“变量名”。
变量是用来存储数据的内存单元,而“数据”不应该狭义的被理解为“数字”,各种符号、字母和汉字也属于数据的范畴。在使用变量的时候必须向编译器交代清楚这个变量中所保存的数据是什么类型,这样编译器才知道要分配多大的内存空间来存储这个数据。那么,在Java语言中,变量都能存储哪些类型的数据呢?想弄清楚这个问题需要先来学习一下Java语言的数据类型。
2.1.1 Java语言基础数据类型
任何编程语言都要与数据打交道,但每种数据的类型各不相同。Java语言按照层层细分的方式对各种类型的数据进行划分,划分结果如图2-1所示。
图2-1 Java数据类型划分
通过图2-1可以看到:Java语言把数据的类型首先划分成数字和非数字两种。数字类型中,又可以划分出整数类型和浮点数型两种。而非数字类型也可以分为字符型和布尔型,下面分别对各种数据类型展开讲解。
1.整数类型
所谓“整数类型”,也叫“整型”,它表示人们通常所说的“整数”。整型数据根据其所能表示数字范围的大小和占据内存空间的大小又可以具体分为4种,它们如表2-1所示。
表2-1 整型数据
类型名称 | 占用空间 | 表示范围 |
byte | 1字节 | -27~27-1 |
short | 2字节 | -215~215-1 |
int | 4字节 | -231~231-1 |
long | 8字节 | -263~263-1 |
通过表2-1可以看出,4种整型数据的名称分别叫做byte、short、int和long,它们所占用的内存空间大小和能表示数据的范围也各不相同。对于所占用的内存空间而言,各位读者可以看出一个明显的特点:4种整型数据从小到大所占用的内存字节数是按1、2、4、8的规律成倍递增的。与此对应的是数据的表示范围,它们也有一定的规律可循:最小值都是-2n,而最大值都是2n-1。另外,表示指数的n也有规律:它们都是字节数×8-1。例如:int型数据占用4字节,所以其指数n就是4×8-1,也就是31。
记住这两个个规律,读者就不必刻意的死记硬背各种整型数据所能表示范围的大小了。有人肯定会问:各种整型数据的表示范围为什么不的“对称”的呢?比如int型的最小值是“-231”,那么对应的最大值应该是“231”,但为什么实际却是“231-1”呢?简单来说,就是因为Java语言把数字0也当成了正数,这样来看,任何一种整型的正负数都是一样多的。
通常情况下,一个整型数字都是用十进制的形式书写的。在程序中,还可以用二进制、八进制和十六进制的形式书写整型数字:
- 二进制书写形式:以0B或0b开头,如0B111
- 八进制书写形式:以0开头,如057
- 十六进制书写形式:以0X或0x开头,如0X235
2.浮点数类型
浮点数类型简称“浮点型”,它是指我们通常所说的非整数,它包含小数部分。比如说3.14就是一个浮点型数据。浮点型数据根据其精度和表示范围的不同,又可以分为“单精度浮点型”和“双精度浮点型”,如表2-2所示。
表2-2 浮点型数据
类型名称 | 占用空间 | 精确度 | |
单精度浮点型 | float | 4字节 | 6-7位有效数字 |
双精度浮点型 | double | 8字节 | 15位有效数字 |
看到表2-2,很多读者都会问:为什么浮点型的数据没有给出明确的表示范围,而是只给出了两种浮点型数据的精确度呢?就是因为计算机无论存储什么类型数据都采用二进制形式,一个有限位数的十进制数小数在转换成二进制数时可能会变成无限小数,因此有可能无法精确的表示出这个数值的真实大小,因此仅能用“有效数字”这样的方式来描述浮点数的精确度,而无法给定一个具体的数值来说明它真正的取值范围。
3.字符型
字符型数据用于表示“单个”字符。这里特意从数量的角度强调“单个”,就是为了提醒各位读者:如果是“多个”字符就变成了“字符串”。另外,有些读者不太理解“字符”这个概念,其实,所谓“字符”就是“符号”的意思。例如@、#、%这些都是符号,它们当然也都是字符。字母a、b、c和数字1、2、3也是符号,甚至一个汉字在Java语言中也可以被看作一个符号,所以它们也都是字符。
在Java语言中,一个变量或方法有可能会被命名为a,为了让编译器能够区分这个a到底表示一个字符还是一个变量的名称,Java语言规定,所有字符必须用单引号引用,所以,当程序中出现一个a,那么它就是一个变量或者是方法的名称,而出现一个’a’,那么它就表示一个字符。
Java语言使用“char”这个关键字来表示字符型数据。char型数据所占内存空间为2个字节,并采用Unicode编码方式。关于“Unicode编码”是什么意思,各位读者暂时无需理解,本书会在《字符串》这一章中详细讲解这个概念。目前来说,大家只要知道:因为Java语言的char型数据采用了Unicode编码,这使得char类型的变量能够存储一个汉字。
为了方便计算机识别和存储各种字符,人们用数字对每一个字符都进行了编码。例如,字符‘A’的编码为65。因此,char型数据的本质其实就是一个数字,更严格来说是一个“正整数”,它甚至可以与其他数字进行加减乘除这样的数学运算。
4.布尔型
所谓布尔型数据,是专门用来表示“真”或者“假”的数据类型。Java语言用“boolean”关键字来表示这种数据类型,它的值只有两个,分别是true和false。其中true表示真,false表示假。那什么才算“真”,什么算“假”呢?很简单,如果某个表述符合事实,那就是“真”,否则就为“假”。比如“1>2”这样的表述显然不符合事实,计算机经过计算后就会认定“1>2”为假,于是用false来表示这个计算的结果。
那么boolean类型的数据在内存中占用多大的空间呢? boolean这种数据类型只有true和false两个值,所以从理论上来讲,它只需要一个bit位就能表示出这两个值。一个字节有8个bit位,但Java语言在分配内存空间的时候,最小分配一个字节的空间,不会精确到bit位。于是给boolean类型数据分配空间就无法精确到bit位这么小的单位。目前的实际情况是:大部分虚拟机产品都会分配4个字节来存放boolean类型的数据,这与前面讲过的int型数据所占用的空间一样大。虽然分配这么大的空间有点浪费,但是却易于虚拟机对内存的管理。
以上讲解的数据类型总共有8种,分别是:byte、short、int、long、float、double、char和boolean。这8种数据类型是Java语言的最基本数据类型,它们被称为“基础数据类型”。后面的章节中还会讲到这8种类型以外的数据类型,Java语言把那些数据类型统称为“引用数据类型”。
2.1.2 变量的声明与使用
本章在一开始的提到要使用变量来存储用户输入的数据。那么,如何在程序中向计算机申请一块内存空间来当作变量呢?首先要说明:“向计算机申请一块内存空间当作变量”这个操作专业上叫做“变量的声明”,其意义就是声明这个变量的存在。任何一个变量在被使用之前,必须先声明它的存在。声明一个变量要按以下格式编写代码:
变量类型变量名称;
其中变量类型就是前文介绍过的那8种基础数据类型。如果希望声明一个int类型的变量,并且给这个变量起名为a,可以用如下语句实现:
int a;
在以上语句中,仅仅是声明了一个变量a,但没有把任何一个具体的整数存放到变量a当中,可以通过下面的语句把一个整数存放到变量a当中:
a=5;
把一个数据存放到变量中的操作叫做“赋值”。而给一个变量首次进行赋值的操作叫做“初始化”。在赋值时所用到的“=”叫做“赋值运算符”,赋值运算符虽然与数学中的“等号”写法相同,但它并不表示“相等”,而是表示把一个数值存放到某个变量中的操作。
在编码过程中,可以在声明变量的同时对这个变量完成赋值的操作,例如:
int a = 5;
另外,也可以使用一条语句一次性声明多个变量,每个变量之间使用逗号(,)隔开,例如:
int a,b,c;
当然,也可以在声明多个变量的同时为每个变量完成赋值:
int a=5,b=6,c=7;
初学者在使用变量的过程中,要注意以下几个细节:
1.使用变量之前必须完成初始化
变量在没有被初始化的状态下是不能被使用的,否则编译器将在代码中提示语法错误,如图2-2所示。
图2-2 使用未经初始化的变量将导致语法错误
从图2-2可以看出,直接打印未经初始化的变量将导致程序出现语法错误,其原因就是未经初始化的变量中没有存储具体的数据,因此不能拿来使用。在IDEA中,一旦出现语法错误,将在出错误的位置下面划出红色波浪线。
2.变量要正确命名
Java语言对变量的命名有着严格的规定:
- 变量名只能由字母、数字、下划线及美元符($)组成
- 变量名不能以数字开头
- 变量名不能是Java语言的关键字和保留字
- 变量名区分大小写
在第三条规定中出现了“保留字”这个概念,在此有必要解释一下它的含义。Java语言是由C++语言发展而来的,而C++又是从C语言发展而来的。因此Java语言的很多关键字与C和C++中的关键字是相同的。但也有一些C和C++中的关键字在Java语言中已经不再使用了,但作为一脉相承的编程语言,Java保留了这些曾经的关键字的历史地位,不允许程序员拿它们当作变量名,故此称为“保留字”。最典型的一个保留字就是“goto”,它在C语言中是关键字,但在Java语言中已经不再使用。关键字和保留字在IDEA的编辑器中都会被显示为同一种颜色。
其实大家没有必要死记硬背这些命名规则。在对变量命名时,只需要做到“见名知意,规范命名”就可以。所谓“见名知意”就是只看到变量名,就基本能知道这个变量表示什么意思。例如:用int型变量表示一个人的年龄,就应该把变量命名为age,用double型变量表示某种商品的价格,就应该把变量命名为price。有意义的变量名对提高程序的可阅读性是很有帮助的。最好不要用asdf或qwe这样毫无意义的名称给变量命名。
所谓“规范命名”就是指对变量命名时要遵循行业内一些约定俗成的规范。目前,行业内大多采用“驼峰命名法”对变量命名。按照这种命名法则,如果变量只有一个单词组成,那么整个单词的所有字母均为小写,如age就是一个符合规范的命名。而如果变量由多个单词组成,则从第二个单词开始,每个单词的首字母大写以表明这是一个新单词的开始,例如studentAge。另外,方法的命名一般也遵循驼峰命名法。
3.不能在作用域之外使用变量
所谓“作用域”就是指变量起作用的范围,它通常由一对大括号来划定。作用域可以是一个方法,也可以是程序员人为用大括号划定的一片范围。在某个作用域内声明的变量,在作用域之外不能被使用,如图2-3所示。
图2-3 变量在作用域之外不可用
图2-3所示的代码片段中,在主方法内人为添加了一对大括号,这对大括号就划定了一个作用域。在该作用域内定义的变量count仅在其作用域内可用,离开作用域就不能使用该变量。在IDEA的代码编辑器中,如果在作用域外使用变量,变量的名称会变成红色以提示程序员不能在作用域之外使用这个变量。
4.同名变量的作用范围不能重合
变量从被声明开始一直到它作用域结束的这一片区域都是它有效的作用范围。如果两个名称相同的变量作用范围出现重合,编译器在重合的作用范围内将无法识别这两个变量而导致出现语法错误,如图2-4所示。
图2-4 同名变量作用范围有重合
在图2-4所示的代码片段中,main()方法内用大括号人为划定了两个区域。代码第7和第10行分别定义了两个同名变量count1。第7行的count1,它的作用范围是从它被声明开始,一直到第8行的右大括号之前,而第10行的count1,它没有被声明在人为划定的作用域内,因此它的作用范围是从它被声明开始(即第10行),一直到第16行主方法的右大括号之前。虽然这两个变量都叫count1,但它们起作用的范围没有重合部分,编译器能够明确的分辨出这两个变量,因此不会出现语法错误。
但在第12行和第14行所声明的两个同名变量count2情况则不同。第12行的count2,它的作用范围是从它被声明开始,一直到主方法第16行的右大括号之前,该作用范围完全覆盖了第14行所声明的count2的作用范围,这使得两个count2的作用范围出现了重合。由于变量名相同,在作用范围重合的区域内编译器无法分辨出这两个变量,因此会出现语法错误。大家在写代码的时候,最好不要在同一个方法中使用同名变量,这样不但能避免出现语法错误,还可以防止程序员对同名变量的使用产生混淆。
除此文字版教程外,小伙伴们还可以点击这里观看我在本站的视频课程学习Java。
标签:Java,变量,作用域,数据类型,int,初探,第二章,数据 From: https://blog.51cto.com/mugexuetang/5976494