Java基础语法
目录1. 概述
Java是SUN公司于1995年开发的一门高级程序设计语言
1.1. 语言特性
优点
- 跨平台——核心特点,JVM
- 面向对象
- 健壮性
- 安全性
- 简单性
- 高性能——即时编译,JIT
缺点
- 语法复杂、严谨
- 架构比较重,适用于大型网站开发
- 并非适用于所有领域
1.2. 开发平台
- Java SE(J2SE)——桌面级应用
- Java EE(J2EE)——服务器端应用
- Java ME(J2ME)——移动终端应用
1.3. 开发环境
![image-20230419223851452](https://cdn.jsdelivr.net/gh/vinchell/images/img/image-20230419223851452.png)
JDK
:Java程序开发工具包,包含JRE
和开发人员使用的工具JRE
:Java程序运行时环境,包含JVM
和运行时所需的核心类库
JDK = JRE + 开发工具集
JRE = JVM + Java SE标准类库
1.4. 开发步骤
![image-20230420135240236](https://cdn.jsdelivr.net/gh/vinchell/images/img/image-20230420135240236.png)
-
编码:编写Java代码,并保存到
.java
格式的源文件中 -
编译:使用javac.exe对源代码进行编译,生成一个或多个字节码文件
.class
(每个对应一个Java类,文件名与类名相同)javac <src_name>.java
-
执行:使用java.exe运行字节码文件
java <class_name>
注意
- 一个源文件可以声明多个类,但最多有一个使用public关键字且该类名必须与源文件名相同
1.5. 注释
-
单行注释:
//
及该行中其后的内容// 这是单行注释
-
多行注释:
/*
和*/
之间的所有内容/* 这是多行注释 ... 注释不参与编译 */
-
文档注释(Java特有):
/**
和*/
之间的所有内容/** 这是文档注释 @author vinchell @version 1.0.0 */
说明
-
文档注释可被javadoc工具解析,生成网页文件形式的说明文档,命令格式为
javadoc -d <out_dir> -version -author <src_name>.java
2. 变量与运算符
2.1. 关键字/保留字
Java语言中具有专门用途的字符序列(单词),全部由
小写字母
组成
概览(50个)
abstract | assert | boolean | break | byte |
---|---|---|---|---|
case | catch | char | class | const* |
continue | default | do | double | else |
enum | extends | final | finally | float |
for | goto* | if | implements | import |
instanceof | int | interface | long | native |
new | package | private | protected | public |
return | strictfp | short | static | super |
switch | synchronized | this | throw | throws |
transient | try | void | volatile | while |
2.2. 标识符
Java中变量、方法、类等要素命名时使用的字符序列
命名规则
- 由大小写英文字母
a-zA-Z
、数字0-9
、下划线_
、美元符$
组成 - 以字母、下划线、美元符开头,不能以数字开头
- 不能使用关键字和保留字,但可以包含关键字和保留字
- 严格区分大小写,无长度限制
命名规范
- 包名:所有字母都使用小写
- 类名、接口名(大驼峰):所有单词的首字母使用大写
- 变量名、方法名(小驼峰):除第一个外,所有单词的首字母使用大写
- 常量名:所有字母都是用大写,单词之间用下划线连接
2.3. 变量
变量是内存中的一个存储区域,该区域的数据可以在同一类型范围内不断变化
- 三要素:数据类型、变量名、存储的值
说明
- 变量只在其作用域内有效
- 同一作用域内变量不能重名
声明语法
// 声明
type varName;
// 声明和初始化
type varName = value;
2.4. 常用数据类型
2.4.1. 基本数据类型(8种)
-
整形(4种)
类型 长度 表数范围 byte 1字节 -128~127 short 2字节 -32768~32767 int(默认) 4字节 -231~231-1 (约21亿) long 8字节 -263~263-1 说明
- Java默认的整数类型为
int
- long类型的字面量(值)末尾需加上
l
或L
- Java默认的整数类型为
-
浮点型(2种)
类型 长度 表数范围 float 4字节 -3.403×1038~3.403×1038 (小数点后7位) double 8字节 -1.798×10308~1.798×10308 (小数点后15~16位) 说明
- 浮点型字面量的两种表示形式:十进制数、科学计数法表示
- Java默认的浮点数类型为
double
- float类型的字面量(值)末尾需加上
f
或F
-
字符型(char,2字节)
- 字符型字面量的四种表示形式:单引号(
''
)括起来的单个字符、Unicode码('\uxxxx'
)、转义字符、ASCII码
- 字符型字面量的四种表示形式:单引号(
-
布尔型(boolean,4字节)
- 字面量只有
true
和false
- Java中0和非0数不能转换为true和false
- 字面量只有
2.4.2. 引用数据类型
类(class)、数组(array)、接口(interface)、枚举(enum)、注解(annotation)、记录(record)
常用引用数据类型
-
字符串(String)
字符串是指内存中连续分布的零个或多个字符
说明
- 字符串字面量是由双引号(
""
)括起来的零个或多个字符 - 字符串与基本数据类型只能进行连接(
+
)运算,结果为字符串
- 字符串字面量是由双引号(
-
数组(Array)
数组是多个类型相同的数据按照一定顺序排列的集合
说明
- 数组的元素可以是任何一种数据类型
- 数组在内存中占据连续的存储空间,且长度确定
- 数组名引用存储空间的首地址,下标(索引)指定元素的相对地址
2.4.3. 数据类型转换
隐式转换
- 规则:表数范围小的类型转换为表数范围大的类型(非存储空间大小)
- 顺序:byte、short、char --> int --> long --> float --> double
- 特例:算术运算中byte、short、char类型自动转换为int类型(避免溢出)
显式转换
-
规则:表数范围大的类型转换为表数范围小的类型(可能造成精度损失)
-
语法
type varName = (type) value;
2.5. 运算符
2.5.1. 算术运算符(7个)
+
、-
、*
、/
、%
、++
、--
说明
%
余数的符号与被模数相同++
、--
不改变变量的数据类型- 前置
++
、--
先运算再取值;后置++
(--
)先取值再运算
2.5.2. 关系运算符(6个)
>
、>=
、<
、<=
、==
、!=
、instanceof
说明
- 关系运算符的结果都是boolean类型
==
、!=
适用于基本数据类型和引用数据类型
2.5.3. 逻辑运算符(6个)
&
、|
、!
、^
、&&
、||
说明
- 逻辑运算符的操作数都是boolean类型,结果也是boolean类型
&&
、||
为短路运算,即左操作数能确定结果时不运算右操作数
2.5.4. 位运算符(7个)
&
、|
、^
、~
、<<
、>>
、>>>
说明
- 位运算符的运算过程基于补码进行
- 无符号右移运算符
>>>
移位后左侧的空位补0(无论正负)
2.5.5. 赋值运算符(12个)
=
、+=
、-=
、*=
、/=
、%=
、&=
、|=
、^=
、>>=
、<<=
、>>>=
说明
=
两侧数据类型不一致时,需要隐式或显示类型转换+=
、-=
、*=
、/=
、%=
不改变变量的数据类型
2.5.6. 条件运算符(1个)
?:
语法
condExpr?trueExpr:falseExpr
说明
- 如果运算后赋值给变量,则trueExpr和falseExpr的类型应相同或能自动转换
- 条件表达式可以改为if-else结构;反之,不成立
- 条件表达式的执行效率略高于if-else结构
2.5.7. 优先级
优先级 | 运算符 | 结合性 |
---|---|---|
1 | () 、[] 、. |
从左到右 |
2 | ++ 、-- 、~ 、! 、+(正) 、-(负) |
从右到左 |
3 | * 、/ 、% |
从左到右 |
4 | +(加) 、-(减) |
从左到右 |
5 | << 、>> 、>>> |
从左到右 |
6 | < 、<= 、>= 、> 、instanceof |
从左到右 |
7 | == 、!= |
从左到右 |
8 | & |
从左到右 |
9 | ^ |
从左到右 |
10 | ` | ` |
11 | && |
从左到右 |
12 | ` | |
13 | ?: |
从右到左 |
14 | = 、+= 、-= 、*= 、/= 、%= 、&= 、` |
=、 <<=、 >>=、 >>>=` |
3. 流程控制
流程控制就是用来控制程序中各语句的执行顺序,从而将其组合成能完成一定功能的逻辑模块
- 三种流程结构:顺序结构、分支结构、循环结构
3.1. 顺序结构
程序从上到下逐行执行,没有任何判断和跳转
3.2. 分支结构
程序根据条件选择性地执行某段代码
3.2.1. if-else
单分支结构
-
语法格式
if (condExpr) { statements }
-
执行流程
计算条件表达式condExpr:值为true,则执行语句statements;否则,不执行
-
流程图
双分支结构
-
语法格式
if (condExpr) { statements1 } else { statements2 }
-
执行流程
计算条件表达式condExpr:值为true,则执行语句statements1;否则,执行语句statements2
-
流程图
多分支结构
-
语法格式
if (condExpr1) { statements1 } else if (condExpr2) { statements2 } ... else { statementsN+1 }
-
执行流程
- 计算条件表达式condExpr1:值为true,则执行语句statements1;否则,执行下一步
- 计算条件表达式condExpr2:值为true,则执行语句statements2;否则,执行下一步
- ……
- 计算条件表达式condExprN:值为true,则执行语句statementsN;否则,执行下一步
- 执行语句statementsN+1
-
流程图
-
说明
- 多分支结构中,
else
分支可以有0个或1个,else if
分支可以有任意个
- 多分支结构中,
3.2.2. switch-case结构
-
语法结构
switch (expr) { case const1: statements1; case const2: statements2; ... default: statementsN+1; }
-
执行流程
- 根据表达式expr的值,依次匹配各个case后的常量
- 如果表达式的值等于constM,则从语句statementsM向下执行,直到遇到break或结构结束
-
流程图
-
说明
- 表达式expr只能是byte、short、char、int、String或枚举类型
- case分支必须是常量且互不相同,不能是变量、表达式
- default分支可以有0个或1个,case分支可以有任意个
- default分支可以在任意位置
3.2.3. 分支嵌套
分支嵌套是指一个分支结构的某个(些)分支中包含另一个(些)分支结构
3.3. 循环结构
程序根据循环条件重复性地执行某段代码
- 循环四要素:循环初始化、循环条件、循环体、循环控制
3.3.1. for循环
-
语法结构
for (loopInit; loopCond; loopCtrl) { loopBody }
-
执行流程
- 执行循环初始化
- 判断循环条件是否满足:满足则执行下一步;否则,跳出循环
- 执行循环体
- 执行循环控制语句,并跳回步骤2
-
流程图
-
说明
- loopInit可以初始化多个变量,中间适用
,
分隔 - loopCtrl可以更新多个变量,中间使用
,
分隔
- loopInit可以初始化多个变量,中间适用
3.3.2. while循环
-
语法结构
loopInit while (loopCond) { loopBody loopCtrl }
-
执行流程
- 执行循环初始化
- 判断循环条件是否满足:满足则执行下一步;否则,跳出循环
- 执行循环体和循环控制,并跳回步骤2
-
流程图
3.3.3. do-while循环
-
语法结构
loopInit do { loopBody loopCtrl } while (loopCond);
-
执行流程
- 执行循环初始化
- 执行循环体和循环控制
- 判断循环条件是否满足:满足则跳回步骤2;否则,跳出循环
-
流程图
3.3.4. 循环嵌套
循环嵌套是指一个循环结构A的循环体中包含另一个循环结构B,习惯上将循环结构A称为外层循环,循环结构B称为内层循环
3.4. 关键字break
和continue
3.4.1. break
结束当前循环或switch
结构,即跳出循环或switch
结构
语法格式
// 无标签:结束最近的循环或switch结构
break;
// 有标签:结束标签指定的循环或switch结构
break label;
3.4.2. continue
结束本次循环,开始下一次循环
语法格式
// 无标签:结束最近循环结构的本次循环,开始下一次循环
continue;
// 有标签:结束标签指定循环结构的本次循环,开始下一次循环
continue label;
4. 数组
数组是多个类型相同的数据按照一定顺序排列的集合
说明
- 数组的元素可以是任何一种数据类型
- 数组在内存中占据连续的存储空间且长度不可更改
- 数组占用空间的大小取决于其长度和元素类型
- 数组中的元素在内存中是依次紧密排列的,即有序的
- 数组名引用存储空间的首地址,下标(索引)指定元素的相对地址
4.1. 一维数组
4.1.1. 声明和初始化
// 静态初始化
type[] arrName = new type[]{value0, value1...}; // 推荐
type arrName[] = new type[]{value0, value1...};
type[] arrName = {value0, value1...}; // 类型推断
// 动态初始化
type[] arrName = new type[nElem]; // 推荐
type arrName[] = new type[nElem];
说明
- 数组变量和数组元素的初始化操作同时进行,称为静态初始化;数组变量和数组元素的初始化操作分开进行,则称为动态初始化
- 静态初始化的数组长度由静态数组的个数决定;动态初始化则需要指定数组元素的个数
4.1.2. 元素访问
arrName[index]
说明
- 数组的长度为
arrName.length
- 数组元素的下标范围为
0~length-1
4.2. 二维数组
4.2.1. 声明和初始化
// 静态初始化
type[][] arrName = new type[][]{{value0, value1...}, {value0, value1...}...}; // 推荐
type arrName[][] = new type[][]{{value0, value1...}, {value0, value1...}...};
type[] arrName[] = new type[][]{{value0, value1...}, {value0, value1...}...};
type[][] arrName = {{value0, value1...}, {value0, value1...}...}; // 类型推断
// 动态初始化
type[][] arrName = new type[nElem1][nElem2]; // 推荐
type arrName[][] = new type[nElem1][nElem2];
type[] arrName[] = new type[nElem1][nElem2];
type[][] arrName = new type[nElem1][]; // 缺省最后一维
4.2.2. 元素访问
// 访问外层元素
arrName[index1]
// 访问内层元素
arrName[index1][index2]
4.3. 默认值
元素类型 | 初始值 |
---|---|
byte、short、int | 0 |
long | 0l |
float | 0.0f |
double | 0.0 |
char | 0或'\u0000' |
boolean | false |
引用类型 | null |
4.4. 说明
- 高维数组本质上是低维数组的嵌套,即高维数组的元素是低维数组的引用
- 各维度数组元素的长度可以相同,也可以不同
- 当前维度数组的长度为
arrName.length
,其数组元素的长度为arrName[index].length
- 维度不同、元素类型的数组视为不同的引用类型,不能相互转换
5. 常用API
5.1. 输入输出
5.1.1. 输入
-
导包
java.util.Scanner
import java.util.Scanner;
-
实例化
Scanner
类Scanner scanner = new Scanner(System.in);
-
调用
nextXxx
方法xxx input = scanner.nextXxx();
-
关闭资源
scanner.close();
5.1.2. 输出
// 控制台输出并换行
System.out.println(output);
// 控制台输出不换行
System.out.print(output);
5.2. 常用类
5.2.1. java.lang.Math
类别 | 方法 | 说明 |
---|---|---|
数学函数 | static double sqrt(double a) | 返回a的平方根 |
随机数 | static double random() | 返回[0.0, 1.0)范围内的随机数 |
5.2.2. java.lang.System
类别 | 方法 | 说明 |
---|---|---|
时间日期 | static long currentTimeMillis() | 返回当前时间戳 |
5.2.3. java.util.Arrays
类别 | 方法 | 说明 |
---|---|---|
拼接 | static String toString(type[] a) | 返回由数组元素组成的字符串(用[] 括起,元素间由, + 分隔) |
排序 | static void sort(type[] a) | 将数组a的元素按照升序排序 |
排序 | static void sort(type[] a, int fromIndex, int toIndex) | 将数组a指定范围[fromIndex, toIndex)内的元素按照升序排序 |
查找 | static int binarySearch(type[] a, type key) | 返回key在有序数组a中的第一次出现的下标,不存在则返回负数 |
查找 | static int binarySearch(type[] a, int fromIndex, int toIndex, type key) | 返回key在有序数组a指定范围[fromIndex, toIndex)内的第一次出现的下标,不存在则返回负数 |
复制 | static type[] copyOf(type[] original, int newLength) | 复制数组original到长度为newLength的新数组中并返回 |
复制 | static type[] copyOfRange(type[] original, int from, int to) | 复制数组original指定范围[from, to)内的元素到长度为newLength的新数组中并返回 |
比较 | static boolean equals(type[] a, type[] b) | 比较数组a、b的元素是否相同 |
比较 | static boolean equals(type[] a, int aFromIndex, int aToIndex, type[] b, int bFromIndex, int bToIndex) | 比较数组a、b指定范围[aFromIndex, aToIndex)、[bFromIndex, bToIndex)内的元素是否相同 |
填充 | static void fill(type[] a, type val) | 用val填充数组a |
填充 | static void fill(type[] a, int fromIndex, int toIndex, type val) | 用val填充数组a的指定范围[fromIndex, toIndex) |
6. 扩展
6.1. Java虚拟机的内存划分
区域名称 | 作用 |
---|---|
虚拟机栈 | 存储正在执行方法的局部变量表(基本数据类型、对象引用)等 |
堆 | 存储对象 |
方法区 | 存储已被JVM加载的类信息、常量、静态变量、即时编译器编译后的代码等 |
本地方法栈 | 本地(native)方法执行期间的内存区域 |
程序计数器 | 存放每一个线程下一条要执行指令的地址 |