一、Java背景
内容
JDK、JRE、JVM
跨平台原理
常用DOS命令、BUG及BUG解决
(一)JDK、JRE、JVM
1. JDK(Java Development Kit):是 Java 开发工具包,是整个 Java 的核心,包括了 Java 运行环境 JRE、Java 工具和 Java 基础类库。
2. JRE( Java Runtime Environment):是 Java 的运行环境,包含 JVM 标准实现及 Java 核心类库。
3. JVM(Java Virtual Machine):是 Java 虚拟机,是整个 Java 实现跨平台的最核心的部分,能够运行以 Java 语言写作的软件程序。所有的 Java 程序会首先被编译为 .class 的类文件,这种类文件可以在虚拟机上执行。
(二)跨平台原理
Java程序并非是直接运行的,Java编译器将Java源程序编译成与平台无关的字节码文件(class文件),然后由Java虚拟机(JVM)对字节码文件解释执行。所以在不同的操作系统下,只需安装不同的Java虚拟机即可实现java程序的跨平台。
(三)常用DOS命令
操作 | 说明 |
---|---|
盘符名称: | 盘符切换。E:回车,表示切换到E盘。 |
dir | 查看当前路径下的内容。 |
cd 目录 | 进入单级目录。cd itheima |
cd .. | 回退到上一级目录。 |
cd 目录1\目录2... | 进入多级目录。cd itheima\JavaSE |
cd \ | 回退到盘符目录。 |
cls | 清屏。 |
exit | 退出命令提示符窗口。 |
(四)BUG及BUG解决
- BUG
在电脑系统或程序中,隐藏着的一些未被发现的缺陷或问题统称为bug(漏洞)。
- BUG的解决
1. 具备识别BUG的能力:多看
2. 具备分析BUG的能力:多思考,多查资料
3. 具备解决BUG的能力:多尝试,多总结
二、Java基础语法
内容
注释、数据类型、变量、常量
关键字、标识符、类型转换
(一)注释
1. 单行注释
// 这是单行注释文字
2. 多行注释
/*
这是多行注释文字
这是多行注释文字
这是多行注释文字
*/
注意:多行注释不能嵌套使用。
3. 文档注释
/**
* 这是文档注释文字
* 这是文档注释文字
* 这是文档注释文字
*/
(二)数据类型
- 计算机存储单元
1. 计算机存储设备的最小信息单元叫 位(bit)—— b
2. 计算机中最基本的存储单元叫 字节(byte)—— B
- 单位换算
1B(字节) = 8bit
1KB = 1024B
1MB = 1024KB
1GB = 1024MB
1TB = 1024GB
- 基本数据类型
数据类型 | 关键字 | 内存占用 | 取值范围 |
---|---|---|---|
整数类型 | byte | 1 | -128 ~ 127 |
short | 2 | -32768 ~ 32767 | |
int(默认) | 4 | -2的31次方 到 2的31次方-1 | |
long | 8 | -2的63次方 到 2的63次方-1 | |
浮点类型 | float | 4 | 负数:-3.402823E+38 到 -1.401298E-45 正数:1.401298E-45 到 3.402823E+38 |
double(默认) | 8 | 负数:-1.797693E+308 到 -4.9000000E-324 正数:4.9000000E-324 到 1.797693E+308 |
|
字符类型 | char | 2 | 0 ~ 65535 |
布尔类型 | boolean | 1 | true,false |
说明:
在java中整数默认是int类型,浮点数默认是double类型。
e+38表示是乘以10的38次方,同样,e-45表示乘以10的负45次方。
(三)变量
- 概述
变量:在程序运行过程中,其值可以发生改变的量。
- 定义格式
格式一
数据类型 变量名 = 初始化值; // 声明变量并赋值
int age = 18;
格式二
数据类型 变量名;
变量名 = 初始化值;
double money;
money = 3.14;
格式三
// 定义int类型的变量a和b,中间使用逗号隔开
int a = 10, b = 20;
// 声明int类型的变量c和d,中间使用逗号隔开
int c,d;
c = 30;
d = 40;
(四)常量
- 概述
常量:在程序运行过程中,其值不可以发生改变的量。
- 定义格式
final 数据类型 常量名 = 常量值;
(五)关键字
- 概述
关键字是指被java语言赋予了特殊含义的单词。
- 特点
1. 关键字的字母全部小写。
2. 常用的代码编辑器对关键字都有高亮显示。
四类 | 数据类型 | 语句 | 修饰 | 法类接包异 |
---|---|---|---|---|
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 |
(六)标识符
- 概述
标识符是用户编程时使用的名字,用于给类、方法、变量、常量等命名。
- 组成规则
1. 由字母、数字、下划线“_”、美元符号“$”组成,第一个字符不能是数字。
2. 不能使用java中的关键字作为标识符。
3. 标识符对大小写敏感(区分大小写)。
- 命名约定
Java中标识符的命名约定:
1. 小驼峰式命名:变量名、方法名
首字母小写,从第二个单词开始每个单词的首字母大写。
2. 大驼峰式命名:类名
每个单词的首字母都大写。
另外,标识符的命名最好可以做到见名知意
(七)类型转换
1. 自动类型转换
- 概述
把一个表示数据范围小的数值或者变量赋值给另一个表示数据范围大的变量。
2. 强制类型转换
- 概述
把一个表示数据范围大的数值或者变量赋值给另一个表示数据范围小的变量。
- 转换格式
强制类型转换格式:目标数据类型 变量名 = (目标数据类型)值或者变量;
- 数据范围
- 注意
1. char类型的数据转换为int类型是按照码表中对应的int值进行计算的。
2. 整数默认是int类型,byte、short和char类型数据参与运算均会自动转换为int类型。
3. boolean类型不能与其他基本数据类型相互转换。
三、运算符
内容
自增自减运算符
算术运算符
位移运算符
关系运算符
位逻辑运算符
逻辑运算符
三元运算符
赋值运算符
(一)自增自减运算符
- 概述
符号 | 作用 | 说明 |
---|---|---|
++ | 自增 | 变量的值加1 |
-- | 自减 | 变量的值减1 |
- 注意事项
1. ++和-- 既可以放在变量的后边,也可以放在变量的前边。
2. 单独使用
++和--无论是放在变量的前边还是后边,结果是一样的。
3. 参与操作
如果放在变量的后边,先拿变量参与操作,后拿变量做++或者--。
如果放在变量的前边,先拿变量做++或者--,后拿变量参与操作。
(二)算术运算符
- 概述
符号 | 作用 | 说明 |
---|---|---|
+ | 加 | 参看小学一年级 |
- | 减 | 参看小学一年级 |
* | 乘 | 参看小学二年级,与“×”相同 |
/ | 除 | 参看小学二年级,与“÷”相同 |
% | 取余 | 获取的是两个数据做除法的余数 |
- 注意
/ 和 % 的区别:两个数据做除法,/ 取结果的商,% 取结果的余数。
整数操作只能得到整数,要想得到小数,必须有浮点数参与运算。
- 字符的"+"操作
1. char类型参与算术运算,使用的是计算机底层对应的十进制数值。需要我们记住三个字符对应的数值:
'a' -- 97 a-z是连续的,所以'b'对应的数值是98,'c'是99,依次递加
'A' -- 65 A-Z是连续的,所以'B'对应的数值是66,'C'是67,依次递加
'0' -- 48 0-9是连续的,所以'1'对应的数值是49,'2'是50,依次递加
2. 算术表达式中包含不同的基本数据类型的值的时候,整个算术表达式的类型会自动进行提升。
提升规则:
byte类型,short类型和char类型将被提升到int类型,不管是否有其他类型参与运算。
整个表达式的类型自动提升到与表达式中最高等级的操作数相同的类型
等级顺序:byte,short,char --> int --> long --> float --> double
tips:正是由于上述原因,所以在程序开发中我们很少使用byte或者short类型定义整数。也很少会使用char类型定义字符,而使用字符串类型,更不会使用char类型做算术运算。
在”+”操作中,如果出现了字符串,这个”+”是字符串连接符,否则就是算术运算。当连续进行“+”操作时,从左到右逐个执行。
特殊情况: 当+号字符串连接符 遇到通过()进行+号连接的数字时,+号为算术运算符
(三)位移运算符(未完成)
(四)关系运算符
- 概述
符号 | 说明 |
---|---|
== | a == b,判断a和b的值是否相等,成立为true,不成立为false |
!= | a != b,判断a和b的值是否不相等,成立为true,不成立为false |
> | a > b,判断a是否大于b,成立为true,不成立为false |
>= | a >= b,判断a是否大于等于b,成立为true,不成立为false |
< | a < b,判断a是否小于b,成立为true,不成立为false |
<= | a <= b,判断a是否小于等于b,成立为true,不成立为false |
- 注意事项
1. 关系运算符的结果都是boolean类型,要么是true,要么是false。
2. 千万不要把“==”误写成“=”,"=="是判断是否相等的关系,"="是赋值。
(五)位逻辑运算符(未完成)
(六)逻辑运算符
1. 逻辑运算符
符号 | 作用 | 说明 |
---|---|---|
& | 逻辑与 | a&b,a和b都是true,结果为true,否则为false |
| | 逻辑或 | a|b,a和b都是false,结果为false,否则为true |
^ | 逻辑异或 | a^b,a和b结果不同为true,相同为false |
! | 逻辑非 | !a,结果和a的结果正好相反 |
2. 短路逻辑运算符
- 概述
符号 | 作用 | 说明 |
---|---|---|
&& | 短路与 | 作用和&相同,但是有短路效果 |
|| | 短路或 | 作用和|相同,但是有短路效果 |
- 原理
&&
在逻辑与运算中,只要有一个表达式的值为false,那么结果就可以判定为false了,没有必要将所有表达式的值都计算出来,短路与操作就有这样的效果,可以提高效率。
||
同理在逻辑或运算中,一旦发现值为true,右边的表达式将不再参与运算。
- 总述
- 逻辑与&,无论左边真假,右边都要执行。
- 短路与&&,如果左边为真,右边执行;如果左边为假,右边不执行。
- 逻辑或|,无论左边真假,右边都要执行。
- 短路或||,如果左边为假,右边执行;如果左边为真,右边不执行。
(七)三元运算符
- 语法格式
关系表达式 ? 表达式1 : 表达式2;
- 原理
问号前面的位置是判断的条件,判断结果为boolean型,
为true时调用表达式1,为false时调用表达式2。
其逻辑为:如果条件表达式成立或者满足则执行表达式1,否则执行第二个。
(八)赋值运算符
- 概述
符号 | 作用 | 说明 |
---|---|---|
= | 赋值 | a=10,将10赋值给变量a |
+= | 加后赋值 | a+=b,将a+b的值给a |
-= | 减后赋值 | a-=b,将a-b的值给a |
*= | 乘后赋值 | a*=b,将a×b的值给a |
/= | 除后赋值 | a/=b,将a÷b的商给a |
%= | 取余后赋值 | a%=b,将a÷b的余数给a |
- 注意
扩展的赋值运算符隐含了强制类型转换。
赋值运算符的作用是将一个表达式的值赋给左边,左边必须是可修改的,不能是常量。
四、流程控制语句
内容
顺序结构
分支结构:if,switch
循环结构:for,while,do...while
循环嵌套
死循环
跳转控制语句
(一)顺序结构
- 概述
顺序结构是程序中最简单最基本的流程控制,没有特定的语法结构,按照代码的先后顺序,依次执行。
- 顺序结构执行流程图
(二)分支结构
if 语句
switch 语句
1. if 语句
if
if...else
if...else...if
1.1 if 语句
- 格式
if (关系表达式) {
语句体;
}
- 执行流程
1. 首先计算关系表达式的值
2. 如果关系表达式的值为true就执行语句体
3. 如果关系表达式的值为false就不执行语句体
4. 继续执行后面的语句内容
1.2 if...else 语句
- 格式
if (关系表达式) {
语句体1;
} else {
语句体2;
}
- 执行流程
1. 首先计算关系表达式的值
2. 如果关系表达式的值为true就执行语句体1
3. 如果关系表达式的值为false就执行语句体2
4. 继续执行后面的语句内容
1.3 if...else...if 语句
- 格式
if (关系表达式1) {
语句体1;
} else if (关系表达式2) {
语句体2;
}
…
else {
语句体n+1;
}
- 执行流程
1. 首先计算关系表达式1的值
2. 如果值为true就执行语句体1;如果值为false就计算关系表达式2的值
3. 如果值为true就执行语句体2;如果值为false就计算关系表达式3的值
4. ...
5. 如果没有任何关系表达式为true,就执行语句体n+1。
2. switch 语句
- 格式
switch (表达式) {
case 1:
语句体1;
break;
case 2:
语句体2;
break;
...
default:
语句体n+1;
break;
}
- 执行流程
- 首先计算出表达式的值
- 其次,和case依次比较,一旦有对应的值,就会执行相应的语句,在执行的过程中,遇到break就会结束。
- 最后,如果所有的case都和表达式的值不匹配,就会执行default语句体部分,然后程序结束掉。
(三)循环结构
for 循环
while 循环
1. for 循环
- 概述
循环语句可以在满足循环条件的情况下,反复执行某一段代码,这段被重复执行的代码被称为循环体语句。
当反复执行这个循环体时,需要在合适的时候把循环判断条件修改为false,从而结束循环,否则循环将一直执行下去,形成死循环。
- 格式
for (初始化语句; 条件判断语句; 条件控制语句) {
循环体语句;
}
- 格式解释
- 初始化语句:用于表示循环开启时的起始状态,简单说就是循环开始的时候什么样
- 条件判断语句:用于表示循环反复执行的条件,简单说就是判断循环是否能一直执行下去
- 循环体语句:用于表示循环反复执行的内容,简单说就是循环反复执行的事情
- 条件控制语句:用于表示循环执行中每次变化的内容,简单说就是控制循环是否能执行下去
- 循环执行流程
1. 执行初始化语句
2. 执行条件判断语句,看其结果是true还是false
如果是false,循环结束
如果是true,继续执行
3. 执行循环体语句
4. 执行条件控制语句
5. 回到 2 继续
2. while 循环
- 格式
while (条件判断语句) {
循环体语句;
条件控制语句;
}
- 循环执行流程
1. 执行初始化语句
2. 执行条件判断语句,看其结果是true还是false
如果是false,循环结束
如果是true,继续执行
3. 执行循环体语句
4. 执行条件控制语句
5. 回到 2 继续
3. do...while 循环
- 格式
do {
循环体语句;
条件控制语句;
}while(条件判断语句);
- 循环执行流程
1. 执行初始化语句
2. 执行循环体语句
3. 执行条件控制语句
4. 执行条件判断语句,看其结果是true还是false
如果是false,循环结束
如果是true,继续执行
5. 回到 2 继续
4. 三种循环的区别
1. 三种循环的区别
for循环和while循环先判断条件是否成立,然后决定是否执行循环体(先判断后执行)
do...while循环先执行一次循环体,然后判断条件是否成立,是否继续执行循环体(先执行后判断)
2. for循环和while的区别
条件控制语句所控制的自增变量,因为归属for循环的语法结构中,在for循环结束后,就不能再次被访问到了
条件控制语句所控制的自增变量,对于while循环来说不归属其语法结构中,在while循环结束后,该变量还可以继续使用
(四)循环嵌套
- 概述
在循环中,继续定义循环
- 理解
请反复理解这句话:
(整个内循环,就是外循环的一个循环体,内部循环体没有执行完毕,外循环是不会继续向下执行的)
- 结论
外循环执行一次,内循环执行一圈
(五)死循环
三种格式
1. for(;;){}
2. while(true){}
3. do {} while(true);
(六)跳转控制语句
1. 跳转控制语句(break)
跳出循环,结束循环
2. 跳转控制语句(continue)
跳过本次循环,继续下次循环
注意: continue只能在循环中进行使用!
五、API
内容
Scanner
Random
(一)Scanner类
- 概述
Scanner类来获取用户的输入
- 步骤
1). 导包
Scanner 类在java.util包下,所以需要将该类导入。导包的语句需要定义在类的上面。
import java.util.Scanner;
2). 创建Scanner对象
// 创建Scanner对象,sc表示变量名,其他均不可变
Scanner sc = new Scanner(System.in);
3). 接收数据
// 表示将键盘录入的值作为int数返回。
int i = sc.nextInt();
(二)Random类
- 概述
Random类提供了产生随机数的功能。
- 步骤
1). 导包
import java.util.Random;
2). 创建对象
Random r = new Random();
3). 产生随机数
//解释:10代表的是一个范围,如果括号写10,产生的随机数就是0-9,括号写20,参数的随机数则是0-19
int num = r.nextInt(10);
六、数组
内容
- 什么是数组
- 数组定义格式(两种)
- 数组初始化(动、静)
- 数组元素访问
- 数组操作的两个常见小问题
- 数组遍历
- 数组最值
- 内存分配(单、多个、多个相同)
(一)什么是数组
数组就是存储数据长度固定的容器,存储多个数据的数据类型要一致。
(二)数组定义格式
1. 第一种(常用)
数据类型[] 数组名
2. 第二种
数据类型 数组名[]
(三)数组初始化
1. 动态初始化
- 什么是动态初始化
数组动态初始化就是只给定数组的长度,由系统给出默认初始化值。
- 动态初始化格式
数据类型[] 数组名 = new 数据类型[数组长度];
2. 静态初始化
- 什么是动态初始化
在创建数组时,直接将元素确定
- 完整版格式
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,...};
- 简化版格式
数据类型[] 数组名 = {元素1,元素2,...};
(四)数组元素访问
- 什么是索引
每一个存储到数组的元素,都会自动的拥有一个编号,从0开始。
这个自动编号称为数组索引(index),可以通过数组的索引访问到数组中的元素。
- 访问数组元素格式
数组名[索引];
(五)数组操作的两个常见小问题
1. 索引越界异常
- 出现原因
public class ArrayDemo {
public static void main(String[] args) {
int[] arr = new int[3];
System.out.println(arr[3]);
}
}
数组长度为3,索引范围是0~2,但是我们却访问了一个3的索引。
程序运行后,将会抛出ArrayIndexOutOfBoundsException 数组越界异常。在开发中,数组的越界异常是不能出现的,一旦出现了,就必须要修改我们编写的代码。
- 解决方案
将错误的索引修改为正确的索引范围即可!
2. 空指针异常
- 出现原因
public class ArrayDemo {
public static void main(String[] args) {
int[] arr = new int[3];
//把null赋值给数组
arr = null;
System.out.println(arr[0]);
}
}
arr = null 这行代码,意味着变量arr将不会在保存数组的内存地址,也就不允许再操作数组了,因此运行的时候会抛出 NullPointerException 空指针异常。在开发中,数组的越界异常是不能出现的,一旦出现了,就必须要修改我们编写的代码。
- 解决方案
给数组一个真正的堆内存空间引用即可!
(六)数组遍历
- 什么是数组遍历
数组遍历:就是将数组中的每个元素分别获取出来,就是遍历。遍历也是数组操作中的基石。
- 对比
public class ArrayTest01 {
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4, 5 };
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[3]);
System.out.println(arr[4]);
}
}
以上代码是可以将数组中每个元素全部遍历出来,但是如果数组元素非常多,这种写法肯定不行,因此我们需要改造成循环的写法。数组的索引是 0 到 lenght-1 ,可以作为循环的条件出现。
public class ArrayTest01 {
public static void main(String[] args) {
//定义数组
int[] arr = {11, 22, 33, 44, 55};
//使用通用的遍历格式
for(int x=0; x<arr.length; x++) {
System.out.println(arr[x]);
}
}
}
(七)数组最值
- 最大值获取
最大值获取:从数组的所有元素中找出最大值。
- 实现思路
1. 定义变量,保存数组0索引上的元素
2. 遍历数组,获取出数组中的每个元素
3. 将遍历到的元素和保存数组0索引上值的变量进行比较
4. 如果数组元素的值大于了变量的值,变量记录住新的值
5. 数组循环遍历结束,变量保存的就是数组中的最大值
- 代码实现
public class ArrayTest02 {
public static void main(String[] args) {
//定义数组
int[] arr = {12, 45, 98, 73, 60};
//定义一个变量,用于保存最大值
//取数组中第一个数据作为变量的初始值
int max = arr[0];
//与数组中剩余的数据逐个比对,每次比对将最大值保存到变量中
for(int x=1; x<arr.length; x++) {
if(arr[x] > max) {
max = arr[x];
}
}
//循环结束后打印变量的值
System.out.println("max:" + max);
}
}
(八)内存分配
目前我们只需要记住两个内存
分别是:栈内存和堆内存
区域名称 | 作用 |
---|---|
寄存器 | 给CPU使用,和我们开发无关。 |
本地方法栈 | JVM在使用操作系统功能的时候使用,和我们开发无关。 |
方法区 | 存储可以运行的class文件。 |
堆内存 | 存储对象或者数组,new来创建的,都存储在堆内存。 |
方法栈 | 方法运行时使用的内存,比如main方法运行,进入方法栈中执行。 |