JAVA基本语法
知识点导图
1. 关键字、保留字、标识符
1.1 关键字
描述
被JAVA语言赋予特殊含义,用于专门用途的字符串(字母均为小写)。
1.2 保留字
描述
现有JAVA版本尚未使用,但以后版本可能会作为关键字使用。
1.3 标识符
描述
对各种变量、方法和类等要素命名时使用的字符序列称为标识符。
规则
- 由26个英文字母大小写,0-9,_ 或 $ 组成;
- 不能以数字开头;
- 不能使用关键字或者保留字;
- 字母区分大小写,无长度限制;
- 不能包含空格
规范
- 包名:多单词组成时所有字母小写;例,xxxyyyzzz
- 类名、接口名:多单词组成时,所有单词的首字母大写;例:XxxYxxZzz
- 变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写;例:xxxYyyZxx
- 常量名:所有字母都大写。多单词时每个单词之间使用下划线分割;例:XXX_YYY_ZZZ
注:JAVA采用Unicode字符集,因此标识符也可使用汉字声明,但不建议使用
2 变量
2.1 基本数据类型分类
类型 | 占用存储空间 | 范围 | 备注 |
---|---|---|---|
byte | 1字节 | -128 ~ 127 | |
short | 2字节 | -215 ~ 215 - 1 | |
int | 4字节 | -231 ~ 231 - 1 | |
long | 8字节 | -263 ~ 263 - 1 | 声明long型常量,须后加 l 或者 L 。 |
float | 4字节 | -3.403E38 ~ 3.403E38 | 单精度,尾数可精确至7位有效数字。 声明float型常量,须后加 f 或 F 。 |
double | 8字节 | -1.789E308 ~ 1.789E308 | 双精度,精度为float的两倍。 |
char | 2字节 | 字符型变量的三种表现形式: 1. 使用单引号括起来的单个字符。 2. 转义字符:使用转义字符’'来将其后的字符转变为特殊字符常量。 3. 只用Unicode值表示:“\uXXXX”,其中XXXX表示一个十六进制。 | |
boolean | 1bit | true、false |
说明
- JAVA中整型常量默认为int型 ;JAVA中浮点型常量默认为double型。
- JAVA中所有字符都使用Unicode编码;编码可参见2.2章节。
- float可表示的数值范围比long大。
2.2 字符集以及编码方式(扩展)
常见字符集以及编码方式:
字符集类型 | 描述 | 大小范围 |
---|---|---|
ASCII | 美国标准信息交换码。 (一共规定了128个字符的编码,占用一个字节的后面7位,最前面的一位统一为0) | 1个字节 |
ISO8859-1 | 拉丁码表,欧洲码表。 | 1个字节 |
GB2312 | 中国的中文编码表。 | 1~2个字节 |
GBK | 中国的中文编码升级,融合了更多的中文文字符号,包含了简体繁体。 | 1~2个字节 |
Unicode | 国际标准码,融合了目前人类使用的所有字符。为每个字符分配唯一的字符码。 | 2个字节 |
UTF-8 | 变长的编码方式。 | 1~6个字节1 |
说明
- GB2312、GBK兼容了ASCII码,所以在GB2312、GBK编码中可以用一个字节表示字母。在解码时,根据字节的第一位是0还是1来区分一个字节还是两个字节。
- ANSI编码,通常指的是平台的默认编码,如英文操作系统中是ISO8859-1,中文系统是GBK。
Unicode字符集只是定义了字符的集合和唯一编号,UTF-8编码则是根据字符的Unicode码根据一定的规则转化为UTF-8。具体转换步骤见图2.1。
以下将具体字符 程
来描述编码为UTF-8步骤,如图2.2。
2.3 基本数据类型之间运算
自动类型提升
规则
当容量小的数据类型的变量与容量大的数据类型的变量做运算时,结果自动提升为容量大的数据类型。
注:这里的容量大小指的是表示数的范围的大小而不是值占用的字节大小;比如,long型占用的字节比float型占用的字节多,但float容量要比long的容量大。
特殊场景
byte、char、short三种类型的变量做运算时(包括相同的类型),结果均为int型。
结论
byte、char、short -> int -> long -> float -> double
强制类型转换
规则
需要使用强转符:()
;
注:强制类型转换,可能导致精度损失。
应用场景
- 使用long定义变量不加
L
,在int数值范围内的会自动提升为long,超出int范围外的则会编译报错。- 使用float定义变量必须加
F
,定义小数时,默认为double类型,不加F
会导致编译报错。
注:整数常量,默认类型为int型;浮点型常量,默认类型为double型。
2.4 进制之间的转换(扩展)
不同进制的表示方式
进制 | 可用数值范围 | 规则 | 表示方式 |
---|---|---|---|
二进制 | 0,1 | 满二进一 | 以0b或者0B开头 |
八进制 | 0-7 | 满8进一 | 以数字0开头 |
十进制 | 0-9 | 满10进一 | |
十六进制 | 0-9以及A-F(不区分大小写) | 满16进一 | 以0x获取0X开头 |
不同进制之间的转换
可使用工具类工具类:Integer类中的toHexString、toOctalString、toBinartString
3 运算符
3.1 算数运算符
符号 | 作用 | 备注 |
---|---|---|
+ | 正号;加号;连接符 | 连接符只能使用在String与其他基本数据类型变量之间。 |
- | 负号;减号 | |
* | 乘号 | |
/ | 除号 | |
% | 取模 | 结果的符号与被模数的符号相同 |
前++ | 先自增1,在运算 | 自增运算不会改变本身变量的数据类型 |
后++ | 先运算,后自增1 | 自增运算不会改变本身变量的数据类型 |
前-- | 先自减1,在运算 | 自减运算不会改变本身变量的数据类型 |
后-- | 先运算,后自减1 | 自减运算不会改变本身变量的数据类型 |
3.2 赋值运算符
符号 | 作用 | 备注 |
---|---|---|
= | 赋值运算 | 支持连续赋值,如:i = j = 10 |
+= | 复合运算符,先进行加法运算,再进行赋值运算 | 不会改变变量本身的数据类型 |
*= | 复合运算符,先进行乘法运算,再进行赋值运算 | 不会改变变量本身的数据类型 |
/= | 复合运算符,先进行除法运算,再进行赋值运算 | 不会改变变量本身的数据类型 |
%= | 复合运算符,先进行取模运算,再进行赋值运算 | 不会改变变量本身的数据类型 |
典型场景举例:
short s1 = 20;
// s1 = s1 + 2; 编译失败,由于short与int做运算其结果自动类型提升为int,在赋值给short类型错误。
s1 += 2 // 编译通过,运行正常,结论:不会改变变量本身的数据类型。
3.3 比较运算符
符号 | 作用 |
---|---|
== | 等于 |
!= | 不等于 |
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
instanceof | 判断某个对象是否为某个类的实例 |
说明
>
、>
、>=
、<=
:只能使用在数值类型的数据之间。==
、!=
:既可以使用在数值类型之间的数据,还可以使用在其他引用类型变量之间。
3.4 逻辑运算符
符号 | 作用 |
---|---|
& | 逻辑与 |
&& | 短路与 |
丨 | 逻辑或 |
丨丨 | 短路或 |
! | 逻辑非 |
^ | 逻辑异或 |
说明
逻辑运算符操作的都是boolean类型的变量,而且结果也是boolean类型。
3.5 位运算符
符号 | 作用 | 备注 |
---|---|---|
<< | 左移 | 在一定范围内,每向左移1位,相当于 * 2。 空位补0,被移除的高位丢弃,空缺位补0 |
>> | 右移 | 在一定范围内,每向左移1位,相当于 / 2。被移位的二进制最高位是0,右移后,空缺位补0;最高位是1,空缺位补1 。 |
>>> | 无符号右移 | 被移二进制最高位无论是0或者1,空缺位都用0补 |
& | 与运算 | |
丨 | 或运算 | |
^ | 异或运算 | |
~ | 取反运算 |
说明
位运算符操作的都是整型的数据。
3.6 三元运算符
符号 | 作用 | 备注 |
---|---|---|
(条件表达式) ? 表达式1 : 表达式2 | 三元运算符 | 该表达式可嵌套使用 |
3.7 运算符优先级
JAVA中运算符优先级:
优先级 | 结合性 | 运算符 |
---|---|---|
1 | 从左向右 | ()、[]、{} |
2 | 从右向左 | !、~、++、- - |
3 | 从左向右 | *、/、% |
4 | 从左向右 | +、- |
5 | 从左向右 | <<、>>、>>> |
6 | 从左向右 | <、<=、>、>=、instanceof |
7 | 从左向右 | ==、!= |
8 | 从左向右 | & |
9 | 从左向右 | ^ |
10 | 从左向右 | 丨 |
11 | 从左向右 | && |
12 | 从左向右 | 丨丨 |
13 | 从左向右 | ?:(三元运算符) |
14 | 从右向左 | =、+=、-=、*=、/=、&=、 |
说明
- 一般而言,单目运算符优先级较高,赋值运算符优先级较低。算术运算符优先级较高,关系和逻辑运算符优先级较低。多数运算符具有左结合性,单目运算符、三目运算符、赋值运算符具有右结合性。
- Java 语言中运算符的优先级共分为 14 级,其中 1 级最高,14 级最低。在同一个表达式中运算符优先级高的先执行。
4 流程控制
流程控制语句可用来控制程序中各语句执行顺序,可以把语句组合成能完成一定功能的小模块。其中有三种基本流程结构:顺序结构
、分支结构
、循环结构
。
4.1 顺序结构
顺序结构的特点是:程序从上到下逐行顺序的执行,中间没有任何判断和跳转。
4.2 分支结构
1. if-else结构
if语句的三种格式:
// 格式1:
if (条件表达式) {
执行代码块;
};
// 格式2:
if (条件表达式) {
执行代码块1;
} else {
执行代码块2;
};
// 格式3:
if (条件表达式1) {
执行代码块1;
} else if (条件表达式2) {
执行代码块2;
...
} else {
执行代码块n;
};
2. switch-case结构
switch-case格式:
switch (表达式) {
case 常量1:
语句1;
break; // 可选
case 常量2:
语句2;
break; // 可选
... ...
case 常量N:
语句N;
break; // 可选
default:
语句;
break; // 可选
}
说明
- switch-case结构中可使用break关键字,表示一旦执行到此关键字,则跳出。该关键字是可选的。
- 根据switch表达式中值,依次匹配各个case中的常量,一旦匹配成功,则进入相应case结构中,调用其执行语句。当调用完执行语句后,则仍然继续向下执行其他case结构中的执行语句,直到遇到break关键字或比switch-case结构末尾结束为止。
- swich结构中的表达式只能是6种数据类型之一:byte、short、char、int、枚举类型(JDK5.0新增)、String(HDK7.0新增)。
- case之后只能声明常量,不能声明范围。
- default结构是可选的。
- 凡是可以使用switch-case的结构,都可以转换为if-else,反之则不成立。
- 当既可以使用switch-case结构,又可以使用if-else结构时,优先选择使用switch-case结构,因为switch-case结构执行效率更高,同时也可以降低代码的圈复杂度。
4.3 循环结构
循环结构是指在某些条件满足的情况下,反复执行特定代码的功能。循环结构主要包括4个要素:初始化条件、循环条件、循环体、迭代条件。
for 循环结构
for 循环结构格式:
for(初始化条件; 循环条件; 迭代条件) {
循环体;
};
while 循环结构
while 循环结构格式:
初始化条件;
while(循环条件) {
循环体;
迭代条件;
};
说明
- for循环与while循环是可以互相转换的。
- for循环与while循环的初始化条件部门的作用范围不同。
do-while 循环结构
do-while 循环结构格式:
初始化条件;
do {
循环体;
迭代条件;
} while (循环条件);
说明
do-while循环至少会执行一次循环体。
5 数组
数组(Array)是根据一定顺序排列的集合,并使用一个名字命名,通过编号的方式对这些数据进行统一管理。其具有以下特点:
- 数组是有序排列的。
- 数组属于引用数据类型的变量。数组的元素既可以是基本数据类型,也可以是引用数据类型。
- 创建数组对象会在内存中开辟一整块连续的内存。
- 数组一旦初始化,其长度就是确定的,一旦确定就不可修改。
常见的数组初始化有两种方式:
- 静态初始化:数组的初始化和数组元素的赋值操作同时进行。
- 动态初始化: 数组的初始化和数组的元素的赋值操作进行分开。
5.1 一维数组
一维数组的声明
// 静态初始化
// 方式一:先声明,后初始化
int[] test1;
test1 = new int[]{1, 2, 3, 4};
// 方式二:声明时初始化
String[] test2 = new String[]{"1", "2", "3"};
// 中括号可放在变量后面,与C的语法相似
String test3[] = new String[] {"1", "2", "3"};
// 方式三:声明时初始化,并自动类型推断
String[] test4 = {"1", "2", "3"};
// 动态初始化
// 方式一:先声明,后初始化
int[] test5;
test5 = new int[5];
// 方式二:声明时初始化
String[] test6 = new String[5];
// 错误的写法
// 错误1:未定义数据长度
int[] err1 = new int[];
// 错误2:不能在左边指定数组长度
int[5] err2 = new int[5];
// 错误3:不能同时指定数组长度与赋值
int[] arr1 = new int[3]{1, 2, 3};
一维数组元素的默认初始化值
- 数组元素是整型:0
- 数组元素是浮点型:0.0
- 数组元素是char型:0或’\u0000’,而非’0’
- 数组元素是boolean型:false
- 数组元素是引用数据类型:null
5.1 二维数组
二维数组的声明
// 静态初始化
// 方式一:先声明,后初始化
int[][] test1;
test1 = new int[][]{{1, 2, 3}, {4, 5}};
// 方式二:声明时初始化
String[][] test2 = new String[][]{{"1", "2"}, {"3"}};
// 中括号可放在变量后面,与C的语法相似
String[] test3[] = new String[][]{{"1", "2"}, {"3"}};
// 方式三:声明时初始化,并自动类型推断
String[][] test4 = {{"1", "2"}, {"3"}};
// 动态初始化:数组的初始化和数组的元素的赋值操作进行分开
// 方式一:先声明,后初始化
int[][] test5;
test5 = new int[5][2];
// 方式二:声明时初始化
String[][] test6 = new String[5][2];
// 方式三:声明时初始化,先只指定一维长度
String[][] test7 = new String[5][];
// 错误的写法
// 错误1:只指定了二维的长度
int[][] err1 = new int[][4];
// 错误2:不能在左边指定数组长度
int[4][3] err2 = new int[][];
// 错误3:不能同时指定数组长度并赋值
int[][] arr1 = new int[4][3]{{1,2,3}, {4,5}, {6,7,8}};
二维数组元素的默认初始化值
针对初始化样例:
int[][] test = new int[2][3]
- 外层元素的初始化值为:地址值。
- 内层元素的初始化值为:与一维数组初始化情况相同。
针对初始化样例:
int[][] test = new int[2][]
- 外层元素的初始化值为:null。
- 内层元素的初始化值为:不能调用,否则报错。
在标准UTF-8编码中,超出基本多语言范围(BMP-Basic Multilingual Plane)的字符被编码为4字节格式,但是在修正的UTF-8编码中,他们由代理编码对(surrogatepairs)表示,然后这些编码对在序列中分别重新编码。因此在标准UTF-8编码中需要4个字节的字符,在修正后的UTF-8编码中将需要6个字节。 ↩︎