准备
JRE 与 JDK
- JRE(Java Runtime Environment Java 运行环境)
- 包括 JVM 和 Java 核心类库,安装后可运行 Java 程序,但无法开发。
- JDK(Java Development Kit, Java 开发工具包)
- 登录 Oracle 官网下载 JDK 1.8.0_202。
- 按照默认路径(推荐)进行安装。
- 使用
cmd
或其他控制台输入java
验证。
Win 10 环境变量配置
基于 Windows 10 专业版 21H2 Windows 环境变量变量名不区分大小写 我们强烈不推荐在系统环境变量中设置
classpath
,那样会污染整个系统环境。在启动JVM时设置classpath
才是推荐的做法。—— 引自廖雪峰
win + R
输入sysdm.cpl
打开系统高级设置 -> 环境变量。(或直接点击 Windows 设置按钮 -> 系统 -> 关于 -> 相关设置 -> 高级系统设置)- 系统变量 -> 新建变量名
JAVA_HOME
,复制粘贴 JDK 安装绝对路径,如C:\Program Files\Java\jdk1.8.0_202
。 - 系统变量 -> Path -> 编辑 -> 新建,环境变量分别为
%JAVA_HOME%\bin
和%JAVA_HOME%\jre\bin
。 - 从 JDK 1.5 开始 CLASSPATH 默认是当前路径,不用再配置。如若需要,则同设置
JAVA_HOME
,新建变量名CLASSPATH
,值为.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar
。 - 使用
cmd
或其他控制台程序,输入javac
,java -version
进行验证。
JAVA_HOME,PATH,CLASSPATH 说明
待补充
入门
第一个 Java 程序
// 记事本编写,保存为 HelloWorld.java
public class HelloWorld{
public static void main(String[] args){
System.out.println("HelloWorld");
}
}
# 使用cmd 进入 HelloWorld .java 的保存目录执行
C:\Users\admin>javac HelloWorld.java
C:\Users\admin>java HelloWorld
注意事项
- 源文件以 .java 为扩展名。
- 程序执行入口是
main()
方法。 - 严格区分大小写。
- 每条语句以英文分号
;
结束。 源文件中有且仅有一个
public class
并且和源文件名保持一致。其他class
个数、名字不限。javac 公共类名
会同时将其他类一起编译。Java 程序执行过程
.java 文件 —(javac)编译器编译—> *.class 字节码文件 —(java) JVM 执行 —> 结果
关键字和保留字
关键字:被 Java 语言赋予了特殊含义,用做专门用途的字符串(单词)
Java 保留字:现有 Java 版本尚未使用,但以后版本可能会作为关键字使用。
常见转义字符
- \t 制表符
- \n 换行
- \ \
- ‘’ 双引号
- ‘ 单引号
- \r 回车
- IDEA 中结果为回到本行首位并用 \r 后的内容完全覆盖前面的内容(无论 \r 后的内容是否比前面的长)
- 控制台结果为回到本行首位并用 \r 后的内容按长度覆盖前面的内容(若长度小于被覆盖内容,被覆盖内容仍然可见后面部分)
注释
- 单行注释
//
- 多行注释
/* */
- 文档注释
/** */
Java 代码规范
- 类、方法的注释,以 javadoc(文档注释) 形式书写.
- 使用 tab 缩进(四个空格)。
- 符号两边各加一个空格。
- 编码使用 UTF-8。
- 代码编写使用行尾风格(推荐)或次行风格。
命名规则
- 由数字、英文字母、下划线_ 或 $ 组成
- 不能使用关键字和保留字,但能包含。
- 严格区分大小写,长度无限制,不能有空格。
命名规范
- 包名:多单词组成时所有字母小写,推荐域名反转,如
com.google.test
- 类名、接口名:多单词组成时,大驼峰(单词首字母大写),如
AaaBbbCcc
- 变量名、方法名:多单词组成时,小驼峰(首字母小写,其他同大驼峰)。
- 常量名:全大写,多单词组成时,下划线做分隔。
变量
简介 可以看作是由内存提供的一个存放数据的容器。一般由数据类型、名称、值构成,根据变量名可以访问到变量(值)。
变量的声明与使用
// 声明并赋值(推荐)
int a = 1;
// 或先声明,再赋值
int b;
b = 1;
// 再使用
System.out.println(a);
System.out.println(b);
变量声明可以同类型,但不能同名。
声明和定义是有区别的,但在 Java 中,并没有像 C/C++ 那样真正的分离声明和定义,因此不必过于纠结。
Java API 文档
API(application programming interface,应用程序编程接口),是 Java 提供的基本编程接口,提供了大量的基础类与方法。
官方提供相应的 API 文档为开发者介绍如何使用这些类和方法。
数据类型
每一种数据都定义了明确的数据类型,并在内存中分配了不同大小的内存空间。
Java 的数据类型有两大类:基本数据类型和应用数据类型。
Java 的数据类型有固定的范围和字段长度(因为 JVM),不受物理机系统的影响。
编码表
ASCII 编码表
Unicode 编码表
UTF-8 编码表
GBK 编码表
GBK 2312
big5 码
基本数据类型
数值型
- 整型:
byte
[1],shor
[2],int
[4],long
[8] - 浮点型:
float
[4],double
[8]
字符型 char
[2]
布尔型 boolean
[1]
整型使用细节
- 默认为
int
若使用long
需要在数值后加l
或L
浮点型使用细节
- 浮点数在机器中存放形式,浮点数=符号位+指数位+尾数位。尾数部分可能丢失,造成精度损失(小数都是近似值)
- 默认为
double
,若使用float
需要在数值后加f
或F
- 科学计数法
3.14*10²
<=>3.14e2
;3.14e-2
负二次方,e 大小写等价。 - 判断浮点数和浮点数除法的结果是否相等:二者之差的绝对值是否在要求精度范围内。
字符型使用细节
- 两个单引号括起来一个字符,可以使用转义字符
\
转为特殊字符常量(如换行符\n
) - 本质是一个整数,可以进行运算。
- 输出是与
Unicode
码对应的字符。因此可以按照Unicode
编码赋值输出对应字符。
布尔型使用细节
- 占一个字节,只允许
true
false
- 适用于逻辑运算。
数据类型转换
自动类型转换 按照精度范围,小范围自动转为大范围。
- char < int < long < float < double
- byte < short < int < long < float < double
细节
- 多类型数据混合运算,系统自动将所有数据转换成精度范围最大的,再计算。结果类型范围为最大的。
- 大精度 —> 小精度,报错。反之,自动转换。
byte
short
二者不会与char
自动转换。byte
short
char
可以进行数值计算,会先转为int
型。boolean
不参与转换
强制类型转换
- 大范围 —> 小范围使用
()
,可能造成精度降低或溢出。 - 只针对最近的操作数有效,使用小括号提升优先级。
char
不能保存 int 变量,需强转。
引用数据类型
- 类(class)
- 接口(interface)
- 数组([])
基本数据类型和 String 类型转换
- 基 —>
String
使用+
拼接""
即可。 String
—> 基,使用基本类型包装类的parseXxx()
方法。
String 常见方法(下标起始 0)
图源 String类的20种常见方法Jacky_Cmd-CSDN博客string类的20种常见方法
运算符
图源菜鸟教程
用于数据的运算、赋值和比较等。
一般包括
- 算术运算符
- 赋值运算符
- 关系运算符
- 逻辑运算符
- 位运算符
- 三元(目)运算符
算数运算符
赋值运算符
关系运算符
逻辑运算符
运算结果为 boolean
位运算符
三元运算符
表达式 ? 布尔值 : 布尔值
instanceof 运算符
检查该对象是否是一个特定类型
运算符优先级
流程控制
三大流程控制语句
- 顺序控制
- 分支控制
- 循环控制
分支控制
单分支 if
双分支 if else
多分支 if ... else if ... else
分支结构可以嵌套
switch 分支结构
switch(表达式){
case 常量1:
语句块1;
break;
...
default: // 可选
语句块;
break
}
如果不同常量执行的语句块相同,则写为
case 常量1:
case 常量2:
语句块;
break;
表达式可以是
byte
short
int
char
enum
。从 Java SE 7 开始支持String
,case
标签必须为字符串常量或字面量。
循环控制
for 循环 for(循环变量初始化;循环条件;循环变量迭代){...}
。
- 循环变量可多个一起初始化,使用
,
隔开,循环条件也一样。 - 多重 for 循环,当最内层 for 循环执行完毕,才执行外层循环。
while 循环 while(条件){...}
- 条件为
true
将继续执行循环体。
do…while() do{...}while(条件)
- 至少执行一次
do
中的循环体,然后再判断条件,为true
则继续执行循环体。
break、continue 和 return
return
使用在方法,表示跳出所在的方法。
break
和 continue
都是终止语句块的继续执行,在此之前的语句都会执行,一般用于跳出语句块(如循环),不同之处在于:
break
完全不会再执行该语句块。continue
结束本次循环,执行下一次循环。
for (int i= 1; i<10;i++){
System.out.println("a"); // 必被执行
if (i == 1) break; // 一旦触发,整个循环结束
System.out.println(i);
}
for (int j= 1; j<10;j++){
System.out.println("a"); // 必被执行
if (j == 1) continue; // 一旦触发,j = 1 的循环结束,执行 j = 2 的
System.out.println(i);
}
数组
数组基础
可以存放多个同一类型的数据。数组也是一种数据类型,是引用类型。
定义数组
// 方式一 动态初始化
elemType[] name = new elemType[num];// num 表示数组大小(元素个数)
// 方式二 动态初始化
elemType[] name;
name = new elemType[num]
// 方式三 静态初始化
elemType[] name = {a,b,...}; // 元素个数即为数组大小
访问数组 name[2]
- 数组下标从 0 开始.
-
注意
数组是相同数据类型元素的集合,数组元素可以是任何数据类型。
- 创建数组后未赋值会有默认值,整型为 0,浮点型 0.0,字符型 \u0000,布尔型 false,引用类型 null。
- 超出数组范围会发生越界异常。
数组赋值机制
以下问题的结果都是要求以原始变量名
将一个数组赋值另一个数组
默认情况下是引用传递,赋的值是地址。
int[] a = {1,2,3};
int[] b = a;
b[0] = 99; // 此时,a 数组也变成 99,2,3
数组拷贝
解决上述问题,利用 for/for each 逐个赋值。
int count = 0;
for(int temp : a){
b[count++] = temp;
}
数组反转
将元素内容反转,两种思路:
- 首尾元素两两交换,进行
length/2
向下取整次。(临时变量) - 或是逆序赋值。(临时数组)
数组扩容
动态给数组添加元素,思路:数组容量已满,新建长度加 1 的数组,原始数组遍历赋值给新数组,并将新添加元素加入新数组末尾。初见排序和查找
外部排序 数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。包括(合并排序法和直接合并排序法)
内部排序 指将需要处理的所有数据都加载到内部存储器中进行排序。包括(交换式排序法、选择式排序法和插入式排序法)冒泡排序
从前往后依次两两比较,后者大于前者则交换位置。一共进行n-1
轮比较,每轮比较n - i
次
二分查找
前提 元素有序且使用顺序存储结构
序列为基数,首尾索引相加/2 (无论从 0 还是 1 开始计数)。
序列为偶数,首尾索引相加/2 再向下取整 (无论从 0 还是 1 开始计数)。二维数组
可以理解为数组元素是数组,且行列个数不强制相等。
形式为elemType[][] name;
可以理解为行列,访问都是指定位置如elemType[1][1]
除此之外还有elemType name[][];
和elemType []name[];
使用方式1——动态初始化
同一位数组,索引是从 0 开始,声明时的仅为大小(个数)// elemType[][] arrName = new elemType[大小][大小];
int[][] arr1 = new int[2][3];
使用方式2——动态初始化
//先声明,再定义(开辟空间)
int[][] arr2;
arr2 = new int[2][3];
使用方式3——动态初始化-列数不确定
//创建二维数组,一个有 3 个一维数组
//虽然看起来有new,但每个一维数组还没有开辟空间
//打印结果为 null 而非一个地址
int[][] arr3 = new int[3][];
// 赋值
for (int i = 0; i < arr2.length; i++) {
// 给每行的一维数组开空间,开多少取决上图
arr2[i] = new int[i+1];
// 指定位置赋值
for (int j = 0; j < arr2[i].length; j++) {
arr2[i][j]=i+1;
}
}
// 打印
for (int[] arr:arr2) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
System.out.println();
}
使用方式4——静态初始化
上述只是为了通过“表格行列”这一概念,更好理解二维数组,进行了格式化。elemType[][] arr4 = {
{elem1,...},
...,
{elem1,...}
};