疯狂Java讲义第五版第3章读书笔记

第3章 数据类型和运算符

  • 3.1注释
  • 3.2 标识符和关键字
    • 3.2.1 分隔符
    • 3.2.2 标识符规则
    • 3.2.3 Java关键字
  • 3.3 数据类型分类
  • 3.4 基本数据类型
    • 3.4.1 整型
    • 3.4.2 字符型
    • 3.4.3 浮点型
    • 3.4.4 数值中使用下画线分隔
    • 3.4.5 布尔型
  • 3.5 基本类型的类型转换
    • 3.5.1 自动类型转换
    • 3.5.2 强制类型转换
    • 3.5.3 表达式类型的自动提升
  • 3.6 直接量
  • 3.7 运算符
    • 3.7.1 算术运算符
    • 3.7.2 赋值运算符
    • 3.7.3 位运算符
      • 3.7.3 非、异或运算符的例子
      • 3.7.3 左移运算符
      • 3.7.3 右移运算符
    • 3.7.4 扩展后的赋值运算符
    • 3.7.5 比较运算符
    • 3.7.6 逻辑运算符
    • 3.7.7 三目运算符
    • 3.7.8 运算符的结合性和优先级
  • 3.8 本章小结

3.1注释

3.2 标识符和关键字

Java语言也和其他编程语言一样,使用标识符作为变量、对象的名字,也提供了系列的关键字用以实现特别的功能。

3.2.1 分隔符

Java语言里的分号(;)、花括号({})、方括号([])、圆括号(())、空格、圆点(.)都具有特殊的分隔作用,因此被统称为分隔符。

3.2.2 标识符规则

标识符就是用于给程序中变量、类、方法命名的符号。
Java语言的标识符必须以字母、下画线()、美元符()开头,后面可以跟任意数目的字母、数字、下画线()和美元符()。此处的字母并不局限于26个英文字母,而且可以包含中文字符、日文字符等。

使用标识符时,需要注意如下规则:

  1. 标识符可以由字母、数字、下画线(_)和美元符()组成,其中数字不能打头。
  2. 标识符不能是Java关键字和保留字,但可以包含关键字和保留字。
  3. 标识符不能包含空格。
  4. 标识符只能包含美元符(),不能包含@、#等其他特殊字符。

3.2.3 Java关键字

Java一共包含51个关键字,如表所示。
疯狂Java讲义第五版第3章读书笔记_第1张图片
enum是从Java 5新增的关键字,用于定义一个枚举。而goto和const这两个关键字也被称为保留字,Java还提供了三个特殊的直接量(literal):true、false和null;Java语言的标识符也不能使用这三个特殊的直接量。

3.3 数据类型分类

Java语言支持的类型分为两类:基本类型(Primitive Type)和引用类型(Reference Type)。
基本类型包括boolean类型和数值类型。数值类型有整数类型和浮点类型。整数类型包括byte、short、int、long、char,浮点类型包括float和double。

提示:
char代表字符型,实际上字符型也是一种整数类型,相当于无符号整数类型。

引用类型包括类、接口和数组类型,还有一种特殊的null类型。

注意:
空引用(null)只能被转换成引用类型,不能转换成基本类型,因此不要把一个null值赋给基本数据类型的变量。

3.4 基本数据类型

疯狂Java讲义第五版第3章读书笔记_第2张图片

3.4.1 整型

通常所说的整型,实际指的是如下4种类型。
byte:一个byte类型整数在内存里占8位,表数范围是-128(-27)~127(27-1)。
short:一个short类型整数在内存里占16位,表数范围是-32768(-215)~32767(215-1)。
int:一个int类型整数在内存里占32位,表数范围是-2147483648(-231)~2147483647(231-1)。
long:一个long类型整数在内存里占64位,表数范围是(-263)~(263-1)。

int是最常用的整数类型,因此在通常情况下,直接给出一个整数值默认就是int类型。除此之外,有如下两种情形必须指出。
➢ 如果直接将一个较小的整数值(在byte或short类型的表数范围内)赋给一个byte或short变量,系统会自动把这个整数值当成byte或者short类型来处理。
➢ 如果使用一个巨大的整数值(超出了int类型的表数范围)时,Java不会自动把这个整数值当成long类型来处理。如果希望系统把一个整数值当成long类型来处理,应在这个整数值后增加l或者L作为后缀。

3.4.2 字符型

字符型通常用于表示单个的字符,字符型值必须使用单引号(’)括起来。

字符型值有如下三种表示形式。

  1. 直接通过单个字符来指定字符型值,例如’A’、'9’和’0’等。
  2. 通过转义字符表示特殊字符型值,例如’\n’、’\t’等。
  3. 直接使用Unicode值来表示字符型值,格式是’\uXXXX’,其中XXXX代表一个十六进制的整数。

Java语言中常用的转义字符疯狂Java讲义第五版第3章读书笔记_第3张图片

3.4.3 浮点型

  • Java的浮点类型有两种:float和double。
  • 对于float型数值,第1位是符号位,接下来8位表示指数,再接下来的23位表示尾数;对于double类型数值,第1位也是符号位,接下来的11位表示指数,再接下来的52位表示尾数。

3.4.4 数值中使用下画线分隔

3.4.5 布尔型

3.5 基本类型的类型转换

3.5.1 自动类型转换

  • Java所有的数值型变量可以相互转换,如果系统支持把某种基本类型的值直接赋给另一种基本类型的变量,则这种方式被称为自动类型转换。
  • 当把一个表数范围小的数值或变量直接赋给另一个表数范围大的变量时,系统将可以进行自动类型转换;否则就需要强制转换。
    疯狂Java讲义第五版第3章读书笔记_第4张图片
    图3.10中所示的箭头左边的数值类型可以自动类型转换为箭头右边的数值类型。

3.5.2 强制类型转换

疯狂Java讲义第五版第3章读书笔记_第5张图片

  • 在上面程序中,把一个浮点数强制类型转换为整数时,Java将直接截断浮点数的小数部分。除此之外,上面程序还把233强制类型转换为byte类型的整数,从而变成了-23,这就是典型的溢出。图3.11示范了这个转换过程。
    疯狂Java讲义第五版第3章读书笔记_第6张图片
  • 从图3.11可以看出,32位int类型的233在内存中如图3.11上面所示,强制类型转换为8位的byte类型,则需要截断前面的24位,只保留右边8位,最左边的1是一个符号位,此处表明这是一个负数,负数在计算机里是以补码形式存在的,因此还需要换算成原码。

原码、反码、补码之间的类型转换。
注意:负数在计算机里是以补码形式存在的!

  • 将补码减1得到反码形式,再将反码取反就可以得到原码。最后的二进制原码为10010111,这个byte类型的值为-(16+4+2+1),也就是-23。

经常上网的读者可能会发现有些网页上会包含临时生成的验证字符串,那么这个随机字符串是如何生成的呢?可以先随机生成一个在指定范围内的int数字(如果希望生成小写字母,就在97~122之间),然后将其强制转换成char类型,再将多次生成的字符连缀起来即可。

public class RandomStr {
    public static void main(String[] args) {
        //随机生成6位小写字母验证码
        //定义一个str
        String str = "";
        //进行六次循环
        for (int i = 0; i < 6; i++) {
            //生成一个97-122之间的int类型整数
            int val = (int) (Math.random()*26+97);
            //将val强制转换位char类型后连接到str后面
            str = str + (char) val;
        }
        System.out.println(str);
    }
}
  • 在通常情况下,字符串不能直接转换为基本类型,但通过基本类型对应的包装类则可以实现把字符串转换成基本类型。
String a = "45";
//使用Integer的方法将一个字符串转换成int类型
int iValue = Integer.parseInt(a);

Java为8种基本类型都提供了对应的包装类:boolean对应Boolean、byte对应Byte、short对应Short、int对应Integer、long对应Long、char对应Character、float对应Float、double对应Double,8个包装类都提供了一个parseXxx(String str)静态方法用于将字符串转换成基本类型。

3.5.3 表达式类型的自动提升

  • 当一个算术表达式中包含多个基本类型的值时,整个算术表达式的数据类型将发生自动提升。
  • 所有的byte类型、short类型和char类型将被提升到int类型。
  • 整个算术表达式的数据类型自动提升到与表达式中最高等级操作数同样的类型。
  • 操作数的等级排列如图3.10所示,位于箭头右边类型的等级高于位于箭头左边类型的等级。
    疯狂Java讲义第五版第3章读书笔记_第7张图片

3.6 直接量

3.7 运算符

Java语言使用运算符将一个或多个操作数连缀成执行性语句,用以实现特定功能。
Java语言中的运算符可分为如下几种。
➢ 算术运算符
➢ 赋值运算符
➢ 比较运算符
➢ 逻辑运算符
➢ 位运算符
➢ 类型相关运算符

3.7.1 算术运算符

3.7.2 赋值运算符

3.7.3 位运算符

Java支持的位运算符有如下7个。

  1. &:按位与。当两位同时为1时才返回1。
  2. |:按位或。只要有一位为1即可返回1。
  3. ~:按位非。单目运算符,将操作数的每个位(包括符号位)全部取反。
  4. ^:按位异或。当两位相同时返回0,不同时返回1。
  5. <<:左移运算符。
  6. >>:右移运算符。
  7. >>>:无符号右移运算符。

一般来说,位运算符只能操作整数类型的变量或值。位运算符的运算法则如表3.3所示。
疯狂Java讲义第五版第3章读书笔记_第8张图片
例:

System.out.println(5 & 9); //将输出1
System.out.println(5 | 9); //将输出13
  • 程序执行的结果是:5&9的结果是1,5|9的结果是13。下面介绍运算原理。
  • 5的二进制码是00000101(省略了前面的24个0),而9的二进制码是00001001(省略了前面的24个0)。运算过程如图3.12所示。
    疯狂Java讲义第五版第3章读书笔记_第9张图片

3.7.3 非、异或运算符的例子

System.out.println(~-5); //将输出4
System.out.println(5 ^ 9); //将输出12
  • 程序执行~-5的结果是4,执行5^9的结果是12。下面通过图3.13来介绍运算原理。
    疯狂Java讲义第五版第3章读书笔记_第10张图片
    疯狂Java讲义第五版第3章读书笔记_第11张图片

3.7.3 左移运算符

  • 左移运算符是将操作数的二进制码整体左移指定位数,左移后右边空出来的位以0填充。
System.out.println(5 << 2); //将输出20
System.out.println(-5 << 2); //将输出-20

疯狂Java讲义第五版第3章读书笔记_第12张图片
在图3.15中,上面的32位数是-5的补码,左移两位后得到一个二进制补码,这个二进制补码的最高位是1,表明是一个负数,换算成十进制数就是-20。

3.7.3 右移运算符

Java的右移运算符有两个:>>和>>>,对于>>运算符而言,把第一个操作数的二进制码右移指定位数后,左边空出来的位以原来的符号位填充,即如果第一个操作数原来是正数,则左边补0;如果第一个操作数是负数,则左边补1。>>>是无符号右移运算符,它把第一个操作数的二进制码右移指定位数后,左边空出来的位总是以0填充

System.out.println(-5 >> 2); //将输出-2
System.out.println(-5 >>> 2); //将输出1073741822

疯狂Java讲义第五版第3章读书笔记_第13张图片
疯狂Java讲义第五版第3章读书笔记_第14张图片

3.7.4 扩展后的赋值运算符

3.7.5 比较运算符

比较运算符用于判断两个变量或常量的大小,比较运算的结果是一个布尔值(true或false)。

==:等于,如果进行比较的两个操作数都是数值类型,即使它们的数据类型不相同,只要它们的值相等,也都将返回true。例如97=='a’返回true,5.0==5也返回true。

如果两个操作数都是引用类型,那么只有当两个引用变量的类型具有父子关系时才可以比较,而且这两个引用必须指向同一个对象才会返回true。Java也支持两个boolean类型的值进行比较,例如,true==false将返回false。

注意:
基本类型的变量、值不能和引用类型的变量、值使用==进行比较;boolean类型的变量、值不能与其他任意类型的变量、值使用==进行比较;如果两个引用类型之间没有父子继承关系,那么它们的变量也不能使用==进行比较。

3.7.6 逻辑运算符

逻辑运算符用于操作两个布尔型的变量或常量。逻辑运算符主要有如下6个。
&&:与,前后两个操作数必须都是true才返回true,否则返回false。
&:不短路与,作用与&&相同,但不会短路
||:或,只要两个操作数中有一个是true,就可以返回true,否则返回false。
|:不短路或,作用与||相同,但不会短路
!:非,只需要一个操作数,如果操作数为true,则返回false;如果操作数为false,则返回true。
^:异或,当两个操作数不同时才返回true,如果两个操作数相同则返回false。

对于|与||的区别,参见如下代码:

//定义变量a,b,并为两个变量赋值
        int a = 5;
        int b = 10;
        // 对a > 4 和 b++ > 10 求或运算
        if (a > 4 | b++ > 10) {
            //输出a的值为5,b的值为11
            System.out.println("a的值为:" + a + ",b的值为:" + b);
        }

执行上面程序,看到输出a的值为5,b的值为11,这表明b++>10表达式得到了计算,但实际上没有计算的必要,因为a>4已经返回了true,则整个表达式一定返回true。

再看如下代码,只是将上面示例的不短路逻辑或改成了短路逻辑或

//定义变量c,d,并为两个变量赋值
        int c = 5;
        int d = 10;
        // 对c > 4 和 d++ > 10 求或运算
        if (a > 4 || b++ > 10) {
            //输出c的值为5,d的值为10
            System.out.println("c的值为:" + c + ",d的值为:" + d);
        }
  • 上面代码执行的结果是:c的值为5,而d的值为10。
  • 对比两段代码,后面的代码仅仅将不短路或改成短路或,程序最后输出的d值不再是11,这表明表达式d++> 10没有获得执行的机会。因为对于短路逻辑或||而言,如果第一个操作数返回true,||将不再对第二个操作数求值,直接返回true。不会计算d++>10这个逻辑表达式,因而d++没有获得执行的机会。因此,最后输出的d值为10。而不短路或|总是执行前后两个操作数。
  • &与&&的区别与此类似:&总会计算前后两个操作数,而&&先计算左边的操作数,如果左边的操作数为false,则直接返回false,根本不会计算右边的操作数。

3.7.7 三目运算符

三目运算符只有一个 a ? b : c,三目运算符的语法格式如下:
在这里插入图片描述
三目运算符的规则是:先对逻辑表达式expression求值,如果逻辑表达式返回true,则返回第二个操作数的值,如果逻辑表达式返回false,则返回第三个操作数的值。

3.7.8 运算符的结合性和优先级

所有的数学运算都认为是从左向右运算的,Java语言中大部分运算符也是从左向右结合的,只有单目运算符、赋值运算符和三目运算符例外,其中,单目运算符、赋值运算符和三目运算符是从右向左结合的,也就是从右向左运算。

运算符有不同的优先级,所谓优先级就是在表达式运算中的运算顺序。表3.4列出了包括分隔符在内的所有运算符的优先级顺序,上一行中的运算符总是优先于下一行的。
疯狂Java讲义第五版第3章读书笔记_第15张图片

3.8 本章小结

  • 本章详细介绍了Java语言的各种基础知识,包括Java代码的三种注释语法,并讲解了如何查阅JDK API文档,这是学习Java编程必须掌握的基本技能。本章讲解了Java程序的标识符规则和数据类型的相关知识,包括基本类型的强制类型转换和自动类型转换。除此之外,本章还详细介绍了Java语言提供的各种运算符,包括算术、位、赋值、比较、逻辑等常用运算符,并详细列出了各种运算符的结合性和优先级。

你可能感兴趣的:(java)