【后端开发】01-Java基础语法

发布时间 2023-10-04 12:11:39作者: timemiser

Java基础语法

1. 概述

Java是SUN公司于1995年开发的一门高级程序设计语言

1.1. 语言特性

优点

  • 跨平台——核心特点,JVM
  • 面向对象
  • 健壮性
  • 安全性
  • 简单性
  • 高性能——即时编译,JIT

缺点

  • 语法复杂、严谨
  • 架构比较重,适用于大型网站开发
  • 并非适用于所有领域

1.2. 开发平台

  • Java SE(J2SE)——桌面级应用
  • Java EE(J2EE)——服务器端应用
  • Java ME(J2ME)——移动终端应用

1.3. 开发环境

image-20230419223851452
  • JDK:Java程序开发工具包,包含JRE和开发人员使用的工具
  • JRE:Java程序运行时环境,包含JVM和运行时所需的核心类库

JDK = JRE + 开发工具集

JRE = JVM + Java SE标准类库

1.4. 开发步骤

image-20230420135240236
  1. 编码:编写Java代码,并保存到.java格式的源文件中

  2. 编译:使用javac.exe对源代码进行编译,生成一个或多个字节码文件.class(每个对应一个Java类,文件名与类名相同)

    javac <src_name>.java
    
  3. 执行:使用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类型的字面量(值)末尾需加上lL
  • 浮点型(2种)

    类型 长度 表数范围
    float 4字节 -3.403×1038~3.403×1038 (小数点后7位)
    double 8字节 -1.798×10308~1.798×10308 (小数点后15~16位)

    说明

    • 浮点型字面量的两种表示形式:十进制数、科学计数法表示
    • Java默认的浮点数类型为double
    • float类型的字面量(值)末尾需加上fF
  • 字符型(char,2字节)

    • 字符型字面量的四种表示形式:单引号('')括起来的单个字符、Unicode码('\uxxxx')、转义字符、ASCII码
  • 布尔型(boolean,4字节

    • 字面量只有truefalse
    • 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;否则,不执行

  • 流程图

    image-20230829204942877

双分支结构

  • 语法格式

    if (condExpr) {
        statements1
    } else {
        statements2
    }
    
  • 执行流程

    计算条件表达式condExpr:值为true,则执行语句statements1;否则,执行语句statements2

  • 流程图

    image-20230829205210250

多分支结构

  • 语法格式

    if (condExpr1) {
        statements1
    }
    else if (condExpr2) {
        statements2
    }
    ...
    else {
        statementsN+1
    }
    
  • 执行流程

    1. 计算条件表达式condExpr1:值为true,则执行语句statements1;否则,执行下一步
    2. 计算条件表达式condExpr2:值为true,则执行语句statements2;否则,执行下一步
    3. ……
    4. 计算条件表达式condExprN:值为true,则执行语句statementsN;否则,执行下一步
    5. 执行语句statementsN+1
  • 流程图

    image-20230829210118691
  • 说明

    • 多分支结构中,else分支可以有0个或1个,else if分支可以有任意个

3.2.2. switch-case结构

  • 语法结构

    switch (expr) {
        case const1: statements1;
        case const2: statements2;
        ...
        default: statementsN+1;
    }
    
  • 执行流程

    1. 根据表达式expr的值,依次匹配各个case后的常量
    2. 如果表达式的值等于constM,则从语句statementsM向下执行,直到遇到break或结构结束
  • 流程图

    image-20230829212213525
  • 说明

    • 表达式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
    }
    
  • 执行流程

    1. 执行循环初始化
    2. 判断循环条件是否满足:满足则执行下一步;否则,跳出循环
    3. 执行循环体
    4. 执行循环控制语句,并跳回步骤2
  • 流程图

    image-20230829224536470
  • 说明

    • loopInit可以初始化多个变量,中间适用,分隔
    • loopCtrl可以更新多个变量,中间使用,分隔

3.3.2. while循环

  • 语法结构

    loopInit
    while (loopCond) {
        loopBody
        loopCtrl
    }
    
  • 执行流程

    1. 执行循环初始化
    2. 判断循环条件是否满足:满足则执行下一步;否则,跳出循环
    3. 执行循环体和循环控制,并跳回步骤2
  • 流程图

    image-20230830104747124

3.3.3. do-while循环

  • 语法结构

    loopInit
    do {
        loopBody
        loopCtrl
    } while (loopCond);
    
  • 执行流程

    1. 执行循环初始化
    2. 执行循环体和循环控制
    3. 判断循环条件是否满足:满足则跳回步骤2;否则,跳出循环
  • 流程图

    image-20230830113000003

3.3.4. 循环嵌套

循环嵌套是指一个循环结构A的循环体中包含另一个循环结构B,习惯上将循环结构A称为外层循环,循环结构B称为内层循环

3.4. 关键字breakcontinue

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. 输入

  1. 导包java.util.Scanner

    import java.util.Scanner;
    
  2. 实例化Scanner

    Scanner scanner = new Scanner(System.in);
    
  3. 调用nextXxx方法

    xxx input = scanner.nextXxx();
    
  4. 关闭资源

    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虚拟机的内存划分

image-20230909114315133

区域名称 作用
虚拟机栈 存储正在执行方法的局部变量表(基本数据类型、对象引用)等
存储对象
方法区 存储已被JVM加载的类信息、常量、静态变量、即时编译器编译后的代码等
本地方法栈 本地(native)方法执行期间的内存区域
程序计数器 存放每一个线程下一条要执行指令的地址

7. 参考资料

  1. 尚硅谷Java零基础全套视频教程(宋红康2023版,java入门自学必备)_哔哩哔哩_bilibili