第2章 Java基本语法

第2章 基本语法

目录

  1. 一、关键字与保留字
  2. 二、标识符(identifier)
  3. 三、变量
  4. 四、每日一考
  5. 五、运算符
  6. 六、流程控制
  7. 七、每日一考
  8. 八、补充

一、关键字与保留字

关键字(keyword)

  • 定义:被Java语言赋予了特殊含义,用作专门用途的字符串(单词)
  • 特点:关键字中所有字母都为小写

Java关键字 Java关键字

保留字(reserved word)

  • Java保留字:现有Java版本尚未使用,但以后版本可能会作为关键字使用。自己命名标识符时要避免使用这些保留字。例如goto、const

二、标识符(identifier)

  • 标识符:
    • Java对各种变量、方法和类等要素命名时使用的字符序列称为标识符
    • 技巧:凡是要起名字的地方就是标识符
  • 命名规则
    • 由26个英文字母大小写、0-9、_或$组成
    • 不可以数字开头
    • 不可使用关键字和保留字,但可包含关键字或保留字
    • Java中严格区分大小写、长度无限制
    • 标识符不能包含空格
  • Java中的名称命名规范
    • 包名:多单词组成时,所有单词都小写(xxyyzz)
    • 类名、接口名:多单词组成时,所有单词首字母大写(XxYyZz)
    • 变量名、方法名:多单词组成时,第一个单词首字母小写、第二个单词开始每个单词首字母大写(xxYyZz)
    • 常量名:所有字母都大写,多单词时每个单词用下划线连接(XX_YY_ZZ)
    • 注意:
      • 在起名字时要见名知意
      • java采用unicode字符集,因此标识符可使用汉字声明,但不建议使用
      • 更多细节详见《代码整洁之道》

三、变量

  • 变量的概念:
    • 内存中的一个存储区域
    • 该区域内数据可在同一类型范围内不断变化
    • 变量是程序中最基本的存储单元。包含变量类型、变量名和存储的值
  • 变量的作用:
    • 用于在内存中保存数据
  • 使用变量时注意:
    • Java中每个变量必须先声明、后使用
    • 使用变量名来访问这块区域的数据
    • 变量作用域:其定义所在的{}内
    • 同一作用域内不能声明两个同名变量
  • 变量分类(按数据类型分类):
    • 基本数据类型(primitive type)
      • 数值型
        • 整数类型(byte、short、int、long)
        • 浮点类型(float、double)
      • 字符型(char)
      • 布尔型(boolean)
    • 引用数据类型(reference type)
      • 类(class) <-- 字符串在这里
      • 接口(interface)
      • 数组([ ])
  • 变量分类(按在类中声明的位置分类):
    • 成员变量(在方法体外,类体内声明的变量称为成员变量)
      • 实例变量(不以static修饰)
      • 类变量(以static修饰)
    • 局部变量(在方法体内部声明的变量称为局部变量)
      • 形参(方法、构造器中定义的变量)
      • 方法局部变量(在方法内定义)
      • 代码块局部变量(在代码块中定义)
    • 成员变量和局部变量在初始化值方面的异同
      • 同:都有生命周期
      • 异:局部变量除形参外,需显式初始化

(一)基本数据类型

整数类型:byte、short、int、long

  • Java中各整数类型有固定的表数范围和字段长度,不受OS影响,以保证Java程序的可移植性
  • Java整型常量默认为int,声明long型常量需要在其后加'l'或‘L’
  • Java中整数类型的位数表(超出对应的类型表数范围 编译报错):
类型占用存储空间表数范围
byte1字节-128 ~ 127
short2字节-\(2^{15}\) ~ \(2^{15}-1\)
int4字节-\(2^{31}\) ~ \(2^{31}-1\)(约21亿)
long8字节-\(2^{63}\) ~ \(2^{63} - 1\) (声明long型变量也需在初始化值后加'l'或‘L’)

浮点型:float、double

  • Java浮点型也有固定的表数范围和字段长度,不受OS影响
  • 浮点型常量有2种表示形式:
    • 十进制形式:5.12、512.0f、.512
    • 科学计数法形式:5.12E2、512E2、100E-2
  • float:单精度,尾数可精确到7位有效数字。多数情况下精度较难满足要求
  • double:双精度,精度是float的两倍,通常采用此类型
  • Java中浮点类型常量默认是double型,声明float型常量需在其后加'f'或'F'
类型占用存储空间表数范围
float4字节-3.403E38 ~ 3.403E38 (定义float变量时,初始化值需要以'f'或'F'结尾)
double8字节-1.798E308 ~ 1.798E308

字符型:char

  • 一个字符占据2字节
  • 定义char类型通常使用一对单引号 ‘ ’,且单引号内部只能有一个字符
  • Java中的所有字符都使用Unicode编码,故可存储任何国家的语言的一个字符
  • char类型表示方式:
    • 声明一个字符(char c = 'A')
    • 转义字符(char c = '\n';)
    • 直接使用Unicode值来表示字符型常量(char c = '\uXXXX'; XXXX代表一个十六进制数)
  • char类型也可进行运算,因为每个字符都有对应的Unicode码
  • win10命令行读取文件默认采用GBK字符集,当文件编码方式不是GBK时某些字符会在输出时乱码。(EditPlus的ANSI即表示GBK编码)

布尔型:boolean

  • 只能取两个值之一:true、false
  • 用于条件判断
  • 转义字符前再加一个\将会输出该转义字符(如:println( "\\\n") );println双引号中需要使用双引号强调某个字符时可在内部双引号前加\(如println( "...\"...\"..." ) )

(二)基本数据类型转换(只有7种类型变量之间的运算,不包含boolean类型)

  • 自动类型提升:

    • 自动类型转换:(不同容量大小的类型变量运算时)容量小的类型自动转换为容量大的数据类型
      • byte、char、short --> int --> long --> float --> double;
      • 此处容量大小指的是表数范围大小
    • 有多种类型的数据混合运算时,系统首先自动将所有数据转换为容量最大的那种数据类型,然后再进行计算。
      • 计算后的数据若不以容量大的类型变量接收,编译报错;
      • 若以浮点型变量接收整形运算结果,输出时会在整数值后加上 .0
    计算后的数据若不以容量大的类型变量接收,编译报错
    • 注意

    • byte、short、char之间不会相互转换,他们三者在混合计算或同种类型运算时首先转换为int类型(java在做运算时如果操作数均在int范围内,那么一律在int的空间内运算)

      byte、short、char 之间不会相互转换,他们三者在混合计算或同种类型运算时首先转换为 int 类型
      byte、short、char 之间不会相互转换,他们三者在混合计算或同种类型运算时首先转换为 int 类型
      • boolean类型不能与其他数据类型运算

      • 当把任何基本数据类型的值和字符串(String)进行连接运算(+)时,基本数据类型的值将自动转化为字符串(String)类型

  • 强制类型转换:自动类型提升的逆运算

    • 需要使用强转符: ()
      • 如:int b1 = (int) d1;
    • 注意:强制类型转换可能导致精度转换(如double转化为int型时会将小数部分截断)

(三)字符串类型:String

  • String类型不是基本数据类型,属于引用数据类型
  • 使用方式与基本数据类型一致。例如:String str = "abcd";
  • 一个字符串可串接另一个字符串、或直接串接其他类型的数据。运算的结果仍是String类型
    • str = str + "xyz";
    • int n = 100;
    • str = str + n; (此处+号为连接运算)
  • 字符型变量在单引号内必须有且只有1个;而字符串在双引号内可存放任意(包含0)个字符

String类型和其他类型运算时的注意点:

String 类型和其他类型运算时的注意点

进制与进制之间的转换

  • 对于整数,计算机中有4种表示方式:
    • 二进制(binary):0, 1。以0b或0B开头
    • 十进制(decimal):0-9
    • 八进制(octal):0-7。以数字0开头
    • 十六进制(hex):0-9及A-F。以0x或0X开头,此处A-F不区分大小写

二进制与十进制之间的转换

  • 二进制:
    • 正数的原码、反码、补码都是一致的
    • 负数的原码为其相反数原码且符号位为1;负数的反码为其原码除符号位取反;负数的补码为其反码+1(或 负数的补码为其相反数的原码取反+1)
    • 计算机的底层都以补码的方式存储数据
  • 十进制转二进制:除2取余的逆

二进制与八进制、十六进制之间的转换

  • 二进制与八进制之间转换:每3位二进制数表示1位八进制数;每1位八进制数表示3位二进制数
  • 二进制与十六进制转换:每4位二进制数表示1位十六进制数;每1位十六进制数表示4位二进制数

四、每日一考

  1. 标识符的命名规则有哪些?

    答:
    • 标识符可由26个英文字母、0-9数字和_以及$组成,且不能以数字开头
    • 不可使用关键字和保留字,但可包含关键字或保留字
    • Java中严格区分大小写、长度无限制
    • 标识符不能包含空格
  2. 标识符的命名规范有哪些?

    答:
    • 包名:所有单词小写
    • 类名和接口名:首字母大写
    • 变量和方法:第一个单词全部小写,从第二个单词开始首字母大写
    • 常量:全部大写,多个单词使用下划线连接
    • 注意:
      • 在起名字时要见名知意
      • java采用unicode字符集,因此标识符可使用汉字声明,但不建议使用
      • 更多细节详见《代码整洁之道》
  3. Java变量按照数据类型怎么划分?并指出Java的基本数据类型有哪8种,并指出各自占用的内存大小

    答:
    • 基本数据类型
      • 数值型
        • 整数型【byte(1字节)、short(2字节)、int(4字节)、long(8字节)】
        • 浮点型【float(4字节)、double(8字节)】
      • 字符型【char(2字节)】
      • 布尔型【boolean】
    • 引用数据类型
      • 类(class)
      • 接口(interface)
      • 数组([ ])
  4. 说明基本数据类型变量之间自动类型提升的运算规则

    答:
    • 在多种类型变量混合运算时,容量小的先转换为容量大的类型,结果为容量最大的类型
    • byte、short、char类型变量混合运算或其中单一类型变量运算时,需首先转换为int类型再进行运算,结果为int类型
    • byte、char、short --> int --> long --> float --> double;
  5. 说明基本数据类型变量之间强制类型转换的使用规则和强转可能出现的问题

    答:
    • 当容量大的类型转换为容量小的类型时需要使用强制类型转换,强制类型转换使用方式:类型A 变量v = (类型A)变量b;
    • 强转可能会损失数据精度

五、运算符

运算符是一种特殊符号,用以表示数据的运算、赋值、比较等。 分类:

  • 算术运算符
  • 赋值运算符
  • 比较运算符(关系运算符)
  • 逻辑运算符
  • 位运算符
  • 三元运算符

(一)算术运算符

Java中的算数运算符
  • 取模(%)运算结果的符号与被模数的符号一致,与模数符号无关
  • 自增1 / 自减1
    • 前++:先自增1,再运算(包括赋值)
    • 后++:先运算(包括赋值),后自增1
    • 自增不会改变变量的数据类型(short b = 1; b++; 中b的类型不会变)
    • 前--和后--类似
    • 自增或自减不能连续使用(num++++; 或 (num++)++; 或 ++num++;),否则会报错
前++和后++测试

(二)赋值运算符

  • 符号:=
  • 扩展:+=,-=,*=,/=,%=;这些运算不会改变结果的数据类型(short i = 2; i += 1; 不会报错,与i = i + 1还是有区别的)
  • 用法:
    • 可连续赋值:i1 = j1 =10;
    • 共同使用一个类型:int i1 = 10, i2 = 9;
    • i1 += 2 等价于 i1 = i1 + 2;(其他类似)
赋值运算与++运算符混合运算测试

(三)比较运算符

Java中的比较运算符
  • 比较运算符的结果都是boolean型
  • < > >= <=只能用于数值类型数据之间
  • == 和 !=:不仅可以使用在数值类型数据之间,还可使用在其他引用类型变量之间(例如new的两个对象比较)

(四)逻辑运算符

​ &:逻辑与;|:逻辑或;!:逻辑非;
​ &&:短路与;||:短路或;^:逻辑异或

  • 逻辑运算符只能用于boolean变量或boolean常量,且结果也为boolean型
  • 短路与/短路或 至少可判断一个boolean量(只要左边boolean能够判断出来最终结果,将不再计算右边的量),而逻辑与/逻辑或需要执行左右两边的boolean量(和左边boolean值无关,都要计算)

(五)位运算符

Java中的位运算符
  • 位运算符操作的都是整型的数据

  • 左右移位:

    • 左移(<<):在一定范围内,无论正负数,每向左移一位,整个数据相当于*2,且右侧补0。超过范围会出现正负数转换

    • 右移(>>)时左侧空出来的位使用原来最高位(符号位)补

    • 无符号右移(>>>)是指无论原数是正数还是负数,最高位都以0补

      面试题: 最高效计算2*8?

      • 答:2<<3 或 8<<1

      交换2个变量值的方法: 使用位运算符交换2个变量值的方法

  • & | ^:操作左右两侧整型量的对应的二进制数

(六)三元运算符

  • 格式:
    • (条件表达式)? 表达式1 : 表达式2;
    • 若条件为真,则执行表达式1;否则执行表达式2
  • 三元运算符和if-else异同:
    • 三元运算符可简化为if-else语句,都可以嵌套使用
    • 三元运算符必须返回一个结果
    • if后代码块可有多个语句

(七)运算符优先级

考试需要记,但优先级表较为难记,只需在编程中把想要优先运算的用小括号括起来即可。

六、流程控制

(一)基本流程结构:

  • 顺序结构
  • 分支结构
    • 根据条件,选择性的执行某段代码
      • 有if-else和switch-case两种分支结构
        • if-else三种结构 if-else三种结构
        • switch-case结构 switch-case结构
  • 循环结构
    • 根据循环条件,重复性执行某段代码
    • 有while、do...while、for三种循环语句
    • 注:JDK1.5提供了foreach循环,方便遍历集合、数组元素

(二)分支结构

if-else结构

  • else结构是可选的
  • 对于条件表达式
    • 如果多个条件表达式之间是互斥的关系,各个条件表达式的顺序无所谓
    • 否则,应根据实际情况考虑应将哪个条件置于前面、哪个置于后面

switch-case结构

格式: switch-case结构

  • 根据switch表达式的值,依次匹配各个case中的常量,一旦匹配成功,则进入相应的case结构中,调用其执行语句,调用完执行语句后仍继续向下执行,直到遇到break或switch-case结尾
  • switch表达式只能是6种数据类型之一:byte、short、int、char、枚举类型(JDK5.0新增)、String类型(JDK7.0新增)
  • case之后只能声明常量,不能是表达式
  • default结构是可有可无的,且位置灵活(置于case前面时也是在所有case不匹配时调用,且该结构仍需先判断各个case)
  • 凡是使用switch-case的结构,都可转换为if-else结构。反之不成立;当写分支结构时,两者都可使用情况下,优先使用switch-case,因为switch-case执行效率稍高

(三)循环结构

循环结构分类

  • 循环语句的四个组成部分:
    • ① 初始化部分(init_statement)
    • ② 循环条件部分(test_exp)
    • ③ 循环体部分(body_statement)
    • ④ 迭代部分(alter_statement)
循环语句的四个组成部分
  • for循环结构:
    • 格式:for(①; ②; ④) { ③ }
    • 执行过程(满足②执行循环体):① ② ③ ④ ② ③ ④ ... ② ③ ④ ②
    • 意义:条件满足时执行循环体
  • while循环结构:
    • 格式:①; while(②) { ③; ④; }
    • 执行过程(满足②执行循环体):① ② ③ ④ ② ③ ④ ... ② ③ ④ ②
    • for循环和while循环可相互转换
    • 意义:当条件满足时执行循环体
  • do-while循环结构:
    • 格式:①; do { ③; ④; }while(②);
    • 执行过程(满足②执行循环体):① ③ ④ ② ③ ④ ... ② ③ ④ ②
    • 意义:执行 循环体,直到条件不满足(直译:执行(do)...在...时(while))
    • 需要注意:while(②)后需要加上分号
  • while(true) {...} 等价于 for(; ; ;) {...}

嵌套循环

  • 嵌套循环:将一个循环结构A置于另一个循环结构B的循环体中,就构成嵌套循环
  • 外层循环:循环结构B相对于循环结构A为外层循环;内层循环:循环结构A相对于循环结构B为内层循环;
  • 例子:输出100以内的所有质数。(质数或素数为 只能被1和它自己整除的自然数) 输出 100 以内的所有质数

特殊关键字使用(break、continue)

  • break与continue
    • break:适用在switch-case 或 循环结构中
    • continue:适用于循环结构中
    • 两者在循环中作用:break在循环中使用为 结束当前循环;continue在循环中为结束当次循环。两者之后都不能直接声明其他语句
  • 带标签的break和continue
    • 不带标签的break执行后默认跳出包裹此关键词的最近的一个循环;不带标签的continue类似
    • 带标签的break执行后会跳出该标签指明的那一层循环;带标签的continue类似 带标签的break和continue测试
    • 使用带标签的break或continue输出100内所有的质数 使用带标签的 break 或 continue 输出 100 内所有的质数

七、每日一考

  1. & 和 && 的异同

    答:&为逻辑与,&&为短路与。逻辑与两侧的表达式都需计算并判断,而短路与在一侧表达式变量使得整个结果成立时即可不再计算并判断右侧表达式

  2. 程序输出 题目

    答:输出44

  3. 定义三个int型变量并赋值,使用三元运算符或者if-else获取这三个数中的较大数的实现

    代码实现
  4. 编写程序,声明2个double型变量并赋值。判断第一个数大于10.0,且第2个数小于20.0,打印两数之和。否则,打印两者的乘积

    代码实现
  5. 交换两个值的代码实现

    答:前文中有3种解决方案

  6. switch后面的表达式可以是哪些数据类型

    答:switch后表达式可跟 6种类型变量:byte、char、short、int、String和枚举类型

  7. 谈谈你对三元运算符、if-else和switch-case结构使用场景的理解

    答:三元运算符为一个运算符,常应用在简单的判断上,并且必须返回一个数据;if-else为流程控制结构,用于控制程序的运行,常应用于在不同范围内的变量执行不同操作的逻辑中,用于判断的表达式必须为boolean类型;switch-case结构也为流程控制结构,常用于变量具有某几个确定值的逻辑中,表达式类型只能取6种类型之一 凡是能使用三元运算符的、switch-case结构的,都能转换为if-else;反之,则不成立。三者都能使用时,优先使用三元运算符或者switch-case结构

  8. 如何从控制台获取String和int类型的变量,并输出?使用代码实现

    答:
    • 首先导包:import java.util.Scanner;
    • 然后实例化对象:Scanner scan = new Scanner(System.in);
    • 通过查询手册,获取String类型变量:String str = scan.next();
    • 通过查询手册,获取int类型变量:int i = scan.nextInt();
  9. 使用for循环遍历100以内的奇数,并计算所有的奇数的和并输出

    代码实现
  10. 循环结构是如何最后退出循环的,有哪些不同的情况请说明。

    答:
    • 不满足循环条件情况下,退出循环
    • break关键字强制退出循环
    • 在方法中可使用return关键字强制停止循环执行
  11. 带标签的break和continue意义

    答:
    • 带标签的break被执行后,将会退出该标签指定的循环结构
    • 带标签的continue被执行后,将会跳过本次该标签指定的循环
  12. 一个数如果恰好等于她的因子之和,这个数就称为”完数“。例如6=1+2+3。编程找出1000以内的所有完数。(因子:除去这个数本身的其他约数)

    代码实现
  13. 说明break和continue使用上的相同点和不同点

    答:
    • break和continue都可用于循环语句中,而break还可用于switch-case语句中
    • break为退出循环,而continue为跳过该次循环,直接执行下一次循环
    • 两者语句之后不能直接声明执行语句。

八、补充

从键盘获取输入数据:

从键盘获取输入数据代码实现