Java 开发从入门到精通(第2版)
上QQ阅读APP看书,第一时间看更新

3.2 数据类型

知识点讲解:

Java中的数据类型可以分为简单数据类型和复杂数据类型两种。简单数据类型是Java的基础类型,包括整数类型、浮点类型、字符类型和布尔类型,这些是本章将重点讲解的内容。复合数据类型则由简单数据类型组成,是用户根据自己的需要定义并实现其意图的类型,包括类、接口、数组。当然,为了便于读者快速理解,也可以将Java中的数据类型分成更简单明了的两大类,即基本类型和引用类型。

3.2.1 为什么要使用数据类型

使用数据类型的根本原因是项目的需要。对程序员来讲,如果一个变量可以是任何形式的值,那么对该变量的操作就很难定义了,而且也很容易出错。通过引入数据类型,我们可以人为地限制变量的可操作范围,从而降低操作难度、降低出错率、提高计算机内存的使用率。项目中势必要处理整数、小数、英文字符、中文字符等元素,这些元素在计算机中都是用不同类型的数据表示的,每种类型的计算机都会分配指定大小的内存来进行处理。例如,遇到short类型,计算机会分配占2字节的内存来处理;遇到int类型,会分配4字节的内存来处理。如果不引入数据类型的概念,要处理整数和英文字符等不同类型的元素,计算机该怎么办?计算机只能设置一块固定大小的内存来处理各种元素,而且假如设置的太小,例如2字节,还可能会发生因为太小而不能处理的情况。如果设置的太大,例如1000字节,则可能会发生因为太大而过度消耗内存的情况。

Java数据类型的具体分类如图3-3所示。

图3-3 Java数据类型的分类

注意:实际上,Java中还存在另外一种基本类型void,它也有对应的包装类java.lang.Void,不过我们无法直接对它进行操作。有关包的知识,将在本书后面的内容中进行讲解。

3.2.2 简单数据类型的取值范围

基本数据类型是本章的重点,Java中的基本数据类型共有三大类,8个品种,分别是字符类型char,布尔类型boolean以及数值类型byte、short、int、long、float、double。数值类型又可以分为整数类型byte、short、int、long和浮点类型float、double。Java中的数值类型不存在无符号的情况,它们的取值范围是固定的,不会随着硬件环境或操作系统的改变而改变。

Java中的简单数据类型是最简单的,主要由byte、short、int、long、char、float、double和boolean组成。在Java语言中,这8种基本类型的具体取值范围如下所示。

❑ byte:8位,1字节,最大数据存储量是255,数值范围是-128~127。

❑ short:16位,2字节,最大数据存储量是65536,数值范围是-32768~32767。

❑ int:32位,4字节,最大数据存储容量是232-1,数值范围是-231~231-1。

❑ long:64位,8字节,最大数据存储容量是264-1,数值范围是-263~263-1。

❑ float:32位,4字节,数值范围是3.4e-45~1.4e38,直接赋值时必须在数字后加上f或F。

❑ double:64位,8字节,数值范围在4.9e-324~1.8e308,赋值时可以加d或D,也可以不加。

❑ boolean:只有true和false两个取值。

❑ char:16位,2字节,存储Unicode码,用单引号赋值。

Java决定了每种简单类型的大小,这些大小并不随机器结构的变化而变化,这种大小的不可更改正是Java程序具有很强移植能力的原因之一。

3.2.3 字符型

在Java程序中,存储字符的数据类型是字符型,用char表示。字符型通常用于表示单个字符,字符常量必须使用单引号“'”括起来。Java语言使用16位的Unicode编码集作为编码方式,而Unicode被设计成支持世界上所有书面语言的字符,包括中文字符,所以Java程序支持各种语言的字符。

在Java程序中,字符型常量有如下3种表示形式。

❑ 直接通过单个字符来指定字符常量,例如’A' '9’和’0’等。

❑ 通过转义字符表示特殊字符常量,例如’\n' '\f’等。

❑ 直接使用Unicode值来表示字符常量,格式是’\uXXXX',其中XXXX代表一个十六进制整数。

实例3-4

输出字符型变量的值

源码路径:daima\3\Zifu.java

实例文件Zifu.java的主要实现代码如下所示。

①public class Zifu 
②{
③   public static void main(String args[])
④   {
⑤      char ch1='\u0001';         //赋值ch1
⑥      char ch2='\u0394';         //赋值ch2
⑦      char ch3='\uffff';         //赋值ch2
⑧      System.out.println(ch1);   //输出ch1
⑨      System.out.println(ch2);   //输出ch2
⑩      System.out.println(ch3);   //输出ch2
⑪   }
⑫ }

拓展范例及视频二维码

范例3-4-01:输出文本字符

源码路径:演练范例\3-4-01\

范例3-4-02:自动类型转换/强制类型转换

源码路径:演练范例\3-4-02\

行①定义一个类,名为Zifu,这个文件的名字必须和类相同,即Zifu.java。

行②④⑪⑫是大括号分隔符。

行⑤⑥⑦分别赋值给3个char类型的变量ch1、ch2和ch3。

行⑧⑨⑩分别使用println()函数输出变量ch1、ch2和ch3的值。

执行后的结果如图3-4所示。

图3-4 执行结果

上述实例的执行结果是一些图形,为什么呢?这是使用Unicode码表示的结果。Unicode定义的国际化字符集能表示到今天为止的所有字符集,如拉丁文、希腊语等几十种语言,大部分字符我们是看不懂的,用户不需要掌握。读者请注意,在执行结果处有一个问号,它有可能是真的问号,也有可能是不能显示的符号。但是为了正常地输出这些符号,该怎么处理?Java提供了转义字符,以“\”开头,十六进制下以“\”和“U”字开头,后面跟着十六进制数。常用的转义字符如表3-1所示。

表3-1 转义字符

3.2.4 整型

整型(int)是有符号的32位整数。整型用在数组、控制语句等多个地方,Java系统会把byte和short自动提升为整型。

int是最常用的整数类型,通常情况下,Java整数常量默认就是int类型。对于初学者来说,需要特别注意如下两点。

(1)如果直接将一个较小的整数常量(在byte或short类型的数值范围内)赋给一个byte或short变量,系统会自动把这个整数常量当成byte或short类型来处理。

(2)使用一个巨大的整数常量(超出int类型的数值表示范围)时,Java不会自动把这个整数常量当成long类型来处理。如果希望Java系统把一个整数常量当成long类型来处理,应在这个整数常量的后面添加l或L作为后缀。通常推荐使用L,因为字母l很容易跟数字1混淆。

实例3-5

通过整型计算正方形和三角形的面积

源码路径:daima\3\zheng.java

实例文件zheng.java的主要实现代码如下所示。

            ①public static void main(String args[]){
            //开始计算正方形面积
            ②  int b=7;                //赋值
            ③  int L=b*4;              //赋值
            ④  int s=b*b;              //赋值
            ⑤  System.out.println("正方形的周长为"+L);
            //输出周长
            ⑥  System.out.println("正方形的面积为"+s);
            //输出面积
            ⑦  //开始计算三角形面积
            ⑧  int a3=5, b3=7;          //赋值
            ⑨  int s3=a3*b3/2;          //计算面积
            ⑩  System.out.println("三角形的面积为"+s3);     //输出面积
            }

拓展范例及视频二维码

范例3-5-01:演示int类型的提升处理

源码路径:演练范例\3-5-01\

范例3-5-02:自动提升数据类型

源码路径:演练范例\3-5-02\

行①是Java程序的入口函数main()。

行②③④分别定义3个int类型的变量b、L和s。其中变量b的初始值是7,变量L的初始值是变量b的值乘以4,变量s的初始值是变量b的平方。

行⑤⑥分别使用println()函数输出变量L和s的值。

行⑧分别定义int类型变量a3的初始值为5,定义int类型变量b3的初始值为7。

行⑨定义int类型变量s3的初始值为变量a3和b3的积,然后除以2。

行⑩使用println()函数输出变量s3的值。

执行后的结果如图3-5所示。其实我们可以把一个较小的整数常量(在int类型的数值表示范围以内)直接赋给一个long类型的变量,这并不因为Java会把这个较小的整数常量当成long类型来处理。Java依然会把这个整数常量当成int类型来处理,只是这个int类型变量的值会自动将类型转换为long类型。

图3-5 执行结果

3.2.5 浮点型

整型数据在计算机中肯定是不够用的,这时候就出现了浮点型数据。浮点型数据用来表示Java中的浮点数,浮点型数据表示有小数部分的数字,总共有两种类型:单精度浮点型(float)和双精度浮点型(double),它们的取值范围比整型大许多,下面对其进行讲解。

1.单精度浮点型—float

单精度浮点型是专指占用32位存储空间的单精度数据类型,在编程过程中,当需要小数部分且对精度要求不高时,一般使用单精度浮点型,这种数据类型很少用,不详细讲解。

2.双精度浮点型—double

双精度浮点型占用64位存储空间,在计算中占有很大的比重,能够保证数值的准确性。

double类型代表双精度浮点数,float类型代表单精度浮点数。double类型的数值占8字节,64位;float类型的数值占4字节,32位。更详细地说,Java语言的浮点数有两种表示形式。

(1)十进制形式:这种形式就是平常简单的浮点数,例如5.12、512.0、0.512。浮点数必须包含一个小数点,否则会被当成int类型处理。

(2)科学记数法形式:例如5.12e2(即5.12×102)或5.12E2(也是5.12×102)。必须指出的是,只有浮点类型的数值才可以使用科学记数形式表示。例如,51200是int类型的值,但512E2则是浮点型的值。

Java语言的浮点型默认是double型,如果希望Java把一个浮点型数值当成float型处理,应该在这个浮点型数值的后面加上f或F。例如:“5.12”代表的是一个double型常量,它占用64位的内存空间;5.12f或5.12F才表示一个float型常量,它占用32位的内存空间。当然,也可以在一个浮点数的后面添加d或D后缀,以强制指定double类型,但通常没必要。

由于Java浮点数使用二进制数据的科学记数法来表示浮点数,因此可能不能精确表示一个浮点数。例如,我们把5.2345556f赋给一个float类型的变量,接着输出这个变量时,会看到这个变量的值已经发生改变。double类型的浮点数则比float类型的浮点数更加精确。即使浮点数的精度足够高(小数点后的数字很多),也依然可能发生这种情况。如果开发者需要精确保存一个浮点数,可以考虑使用BigDecimal类。

实例3-6

使用浮点型计算圆的面积

源码路径:daima\3\Syuan.java

实例文件Syuan.java的主要实现代码如下所示。

        public class Syuan{
            public static void main(String args[]){
        ①        double r=45.0324;            //赋值
        ②        final double PI=3.1415926; //赋值
        ③        double area=PI*r*r;          //面积计算
        ④        System.out.println("圆的面积是: S="+area);
        //输出面积
            }
        }

拓展范例及视频二维码

范例3-6-01:演示不同浮点型的用法

源码路径:演练范例\3-6-01\

范例3-6-02:实现自动类型转换

源码路径:演练范例\3-6-02\

行①定义一个double类型的变量r,表示圆的半径,设置初始值是45.0324。

行②定义一个double类型的变量PI,设置初始值是3.1415926。这里使用关键字final修饰变量PI,在Java程序中,我们用final修饰符来表示常量,变量一旦赋值后就无法改变。所以此处的PI为常量,值永远是3.1415926。

行③定义一个double类型的变量area,表示圆的面积,设置其值是变量(其实是常量)PI的值乘以变量r的平方。

行④使用println()函数输出变量area的值。

执行后的结果如图3-6所示。

图3-6 使用浮点型计算圆的面积

3.2.6 布尔型

布尔型是一种表示逻辑值的简单类型,它的值只能是真或假这两个值中的一个。它是所有诸如a<b这样的关系运算的返回类型。Java中的布尔型对应只有一种——boolean类型,用于表示逻辑上的“真”或“假”。boolean类型的值只能是true或false,不能用0或非0来代表。布尔类型在if、for等控制语句的条件表达式中比较常见,在Java语言中使用boolean型变量的控制流程主要有下面几种。

❑ if条件控制语句

❑ while循环控制语句

❑ do循环控制语句

❑ for循环控制语句

实例3-7

复制布尔型变量并输出结果

源码路径:daima\3\Bugu.java

实例文件Bugu.java的主要实现代码如下所示。

  public static void main(String args[]) {
  ①          boolean b;               //定义变量b
  ②          b = false;               //赋值
  ③          System.out.println("b is " + b);
  ④          b = true;                //赋值
  ⑤            System.out.println("b is " + b);
                //输出b的值
                //布尔值可以控制if语句的运行
  ⑥            if(b) System.out.println("This is executed.");
  ⑦                    b = false;     //赋值
                //布尔值可以控制if语句的运行
  ⑧            if(b) System.out.println("This is not executed.");
  ⑨                    System.out.println("10 > 9 is " + (10 > 9));
  }

拓展范例及视频二维码

范例3-7-01:定义两个布尔型变量并赋值

源码路径:演练范例\3-7-01\

范例3-7-02:实现强制类型转换

源码路径:演练范例\3-7-02\

行①定义一个boolean类型的变量b。

行②设置变量b的初始值是false。

行③⑤使用println()函数输出变量b的值。

行④重新设置变量b的值是true。

行⑥在Java程序中,布尔值可以控制if语句的运行。因为本行中变量b的值是true,所以会运行if(b)后面的输出语句,在后面使用println()函数输出文本“This is executed.”。

行⑦重新设置变量b的值是false。

在行⑧中,因为本行中变量b的值是false,所以不会运行if(b)后面的println()输出语句。

行⑨使用println()函数输出“10 > 9”的运算结果。

执行后的结果如图3-7所示。

图3-7 使用布尔型变量