第一章 HelloWorld入门程序
1.1 程序开发步骤说明
Java程序开发三步骤:编写、编译、运行。
1.2 编写Java源程序
- 在d:\day01 目录下新建文本文件,完整的文件名修改为HelloWorld.java ,其中文件名为HelloWorld ,后缀名必须为.java 。
- 用记事本打开。
使用notepad++记事本软件。
- 在文件中键入文本并保存,代码如下:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
文件名必须是HelloWorld ,保证文件名和类的名字是一致的,注意大小写。
每个字母和符号必须与示例代码一模一样。
1.3 编译Java源文件并运行Java程序
- 在DOS命令行中,进入Java源文件的目录,使用javac 命令进行编译。
命令:
javac Java源文件名.后缀名
举例:
javac HelloWorld.java
-
编译成功后,命令行没有任何提示。打开 d:\day01 目录,发现产生了一个新的文件 HelloWorld.class ,该文件就是编译后的文件,是Java的可运行文件,称为字节码文件,有了字节码文件,就可以运行程序了。
-
在DOS命令行中,进入Java源文件的目录,使用 java 命令进行运行。
命令:
java 类名字
举例:
java HelloWorld
java HelloWord 不要写 不要写 不要写 .class
1.4 标识符
-
标识符:是指在程序中,我们自己定义内容。比如类的名字、方法的名字和变量的名字等等,都是标识符。
- HelloWorld案例中,出现的标识符有类名字HelloWorld 。
-
命名规则: 硬性要求
- 标识符可以包含英文字母26个(区分大小写) 、0-9数字 、$(美元符号)和_(下划线)。
- 标识符不能以数字开头。
- 标识符不能是关键字。
-
命名规范: 软性建议
- 类名规范:首字母大写,后面每个单词首字母大写(大驼峰式。
- 方法名规范: 首字母小写,后面每个单词首字母大写(小驼峰式)。
- 变量名规范:全部小写。
第二章 常量
2.1 概述
常量:是指在Java程序中固定不变的数据。
2.2 分类
| 类型 | 含义 | 数据举例 |
|---|---|---|
| 整数常量 | 所有的整数 | 0,1,567,-9 |
| 小数常量 | 所有的小数 | 0.0,-0.1,2.55 |
| 字符常量 | 单引号引起来,只能写一个字符,必须有内容 | 'a',' ','好' |
| 字符串常量 | 双引号引起来,可以写多个字符,也可以不写 | "A","Hello","你好","" |
| 布尔常量 | 只有两个值(流程控制中讲解) | true,false |
| 空常量 | 只有一个值(引用数据类型中讲解) | null |
第三章 变量和数据类型
3.1 变量概述
- 变量:常量是固定不变的数据,那么在程序中可以变化的量称为变量。
- Java中要求一个变量每次只能保存一个数据,必须要明确保存的数据类型。
3.2 数据类型
数据类型分类
Java的数据类型分为两大类:
- 基本数据类型:包括 整数、浮点数、字符、布尔。
- 引用数据类型:包括 类、数组、接口。
基本数据类型
四类八种基本数据类型:
| 数据类型 | 关键字 | 内存占用 | 取值范围 |
|---|---|---|---|
| 字节型 | byte | 1个字节 | -128~127 |
| 短整型 | short | 2个字节 | -32768~32767 |
| 整型 | int(默认) | 4个字节 | -231次方~2的31次方-1 |
| 长整型 | long | 8个字节 | -2的63次方~2的63次方-1 |
| 单精度浮点数 | float | 4个字节 | 1.4013E-45~3.4028E+38 |
| 双精度浮点数 | double(默认) | 8个字节 | 4.9E-324~1.7977E+308 |
| 字符型 | char | 2个字节 | 0-65535 |
| 布尔类型 | boolean | 1个字节 | true,false |
Java中的默认类型:
整数类型是int 、浮点类型是double。
3.3 变量的定义
变量定义的格式包括三个要素: 数据类型 、 变量名 、 数据值 。
格式
数据类型 变量名 = 数据值;
long类型:建议数据后加L表示。 float类型:建议数据后加F表示。
3.4 注意事项
- 变量名称:在同一个大括号范围内,变量的名字不可以相同。
- 变量赋值:定义的变量,不赋值不能使用。
第四章 数据类型转换
4.1 自动转换
一个int 类型变量和一个byte 类型变量进行加法运算, 结果会是什么数据类型?
int i = 1;
byte b = 2;
运算结果,变量的类型将是 int 类型,这就是出现了数据类型的自动类型转换现象。
- 自动转换:将取值范围小的类型自动提升为取值范围大的类型 。
byte、short、char‐‐>int‐‐>long‐‐>float‐‐>double
4.2 强制转换
将1.5 赋值到 int 类型变量会发生什么?产生编译失败,肯定无法赋值。
int i = 1.5; // 错误
想要赋值成功,只有通过强制类型转换,将double 类型强制转换成int 类型才能赋值。
- 强制类型转换:将取值范围大的类型强制转换成取值范围小的类型。
- 转换格式:
数据类型 变量名 = (数据类型)被转数据值;
将1.5 赋值到int 类型,代码修改为:
// double类型数据强制转成int类型,直接去掉小数点。
int i = (int)1.5;
强烈注意:
- 浮点转成整数,直接取消小数点,可能造成数据损失精度。
- int 强制转成short 砍掉2个字节,可能造成数据丢失。
4.3 ASCII编码表
| 字符 | 数值 |
|---|---|
| 0 | 48 |
| 9 | 57 |
| A | 65 |
| Z | 90 |
| a | 97 |
| z | 122 |
第五章 运算符
5.1 算数运算符
- ++ 运算,变量自己增长1。反之, -- 运算,变量自己减少1,用法与++ 一致。
- 独立运算:
- 变量在独立运算时, 前++ 和后++ 没有区别 。
- 变量前++ :例如 ++i 。
- 变量后++ :例如 i++ 。
- 混合运算:
- 和其他变量放在一起, 前++ 和后++ 就产生了不同。
- 变量前++ :变量a自己加1,将加1后的结果赋值给b,也就是说a先计算。a和b的结果都是2。
- 变量后++ :变量a先把自己的值1,赋值给变量b,此时变量b的值就是1,变量a自己再加1。a的结果是2,b的结果是1。
- 独立运算:
- +符号在字符串中的操作:
- +符号在遇到字符串的时候,表示连接、拼接的含义。
- "a"+"b"的结果是“ab”,连接含义
5.2 赋值运算符
| 值运算符包括 | 符号 |
|---|---|
| = | 等于号 |
| += | 加等于 |
| -= | 减等于 |
| *= | 乘等于 |
| /= | 除等于 |
| %= | 取模等 |
5.3 比较运算符
比较运算符,是两个数据之间进行比较的运算,运算结果都是布尔值true 或者false 。
5.4 逻辑运算符
逻辑运算符,是用来连接两个布尔类型结果的运算符,运算结果都是布尔值true 或者false 。
5.5 三元运算符
- 三元运算符格式:
数据类型 变量名 = 布尔类型表达式?结果1:结果2
第六章 方法入门
6.1 方法的定义
- 定义格式:
修饰符 返回值类型 方法名 (参数列表){
代码...
return ;
}
- 定义格式解释:
- 修饰符: 目前固定写法 public static 。
- 返回值类型: 目前固定写法 void ,其他返回值类型在后面的课程讲解。
- 方法名:为我们定义的方法起名,满足标识符的规范,用来调用方法。
- 参数列表: 目前无参数, 带有参数的方法在后面的课程讲解。
- return:方法结束。因为返回值类型是void,方法大括号内的return可以不写。
6.2 注意事项
- 方法定义注意事项:
- 方法必须定义在一类中方法外
- 方法不能定义在另一个方法的里面
第七章 JShell脚本工具
什么时候会用到JShell 工具呢,当我们编写的代码非常少的时候,而又不愿意编写类,main方法,也不愿意去编译和运行,这个时候可以使用JShell工具。JShell工具,只适合片段代码的测试。
- 启动JShell工具,在DOS命令行直接输入JShell命令。
- 接下来可以编写Java代码,无需写类和方法,直接写方法中的代码即可,同时无需编译和运行,直接回车即可。
第八章 扩展知识点
8.1 +=符号的扩展
下面的程序有问题吗?
public static void main(String[] args){
short s = 1;
s+=1;
System.out.println(s);
}
分析:
s += 1 逻辑上看作是s = s + 1 计算结果被提升为int类型,再向short类型赋值时发生错误,因为不能将取值范围大的类型赋值到取值范围小的类型。但是, s=s+1进行两次运算, += 是一个运算符,只运算一次,并带有强制转换的特点,也就是说s += 1 就是s = (short)(s + 1) ,因此程序没有问题编译通过,运行结果是2.
8.2 常量和变量的运算
下面的程序有问题吗?
public static void main(String[] args){
byte b1=1;
byte b2=2;
byte b3=1 + 2;
byte b4=b1 + b2;
System.out.println(b3);
System.out.println(b4);
}
分析:
b3 = 1 + 2 , 1 和 2 是常量,为固定不变的数据,在编译的时候(编译器javac),已经确定了1+2 的结果并没有超过byte类型的取值范围,可以赋值给变量b3 ,因此b3=1 + 2 是正确的。
反之, b4 = b1 + b2 , b1 和 b2 是变量,变量的值是可能变化的,在编译的时候,编译器javac不确定b1+b2的结果是什么,因此会将结果以int类型进行处理,所以int类型不能赋值给byte类型,因此编译失败。
第九章 判断语句
9.1 判断语句1--if
9.2 判断语句2--if...else
9.3 判断语句3--if..else if...else
9.4 if语句和三元运算符的互换
第十章 选择语句
10.1 选择语句--switch
- switch语句格式:
switch(表达式) {
case 常量值1:
语句体1;
break;
case 常量值2:
语句体2;
break;
...
default:
语句体n+1;
break;
}
- 执行流程
- 首先计算出表达式的值
- 其次,和case依次比较,一旦有对应的值,就会执行相应的语句,在执行的过程中,遇到break就会结束。
- 最后,如果所有的case都和表达式的值不匹配,就会执行default语句体部分,然后程序结束掉。
10.2 case的穿透性
在switch语句中,如果case的后面不写break,将出现穿透现象,也就是不会在判断下一个case的值,直接向后运 行,直到遇到break,或者整体switch结束。
第十一章 循环语句
11.1 循环语句1--for
- for循环语句格式:
for(初始化表达式①; 布尔表达式②; 步进表达式④){
循环体③
}
11.2 循环语句2--while
- while循环语句格式:
初始化表达式①
while(布尔表达式②){
循环体③
步进表达式④
}
11.3 循环语句3--do...while
- do...while循环格式
初始化表达式①
do{
循环体③
步进表达式④
}while(布尔表达式②);
do...while循环的特点:无条件执行一次循环体,即使我们将循环条件直接写成false,也依然会循环一次。这样的 循环具有一定的风险性,因此初学者不建议使用do...while循环。
11.4 循环语句的区别
- for 和 while 的小区别:
- 控制条件语句所控制的那个变量,在for循环结束后,就不能再被访问到了,而while循环结束还可以继续使用,如果你想继续使用,就用while,否则推荐使用for。原因是for循环结束,该变量就从内存中消失,能够提高内存的使用效率。
- 在已知循环次数的时候使用推荐使用for,循环次数未知的时推荐使用while。
11.5 跳出语句
break
- 使用场景:终止switch或者循环
- 在选择结构switch语句中
- 在循环语句中
- 离开使用场景的存在是没有意义的
continue
- 使用场景:结束本次循环,继续下一次的循环
第十二章 数组定义和访问
12.1 数组的定义
方式一
- 格式:
数组存储的数据类型[] 数组名字 = new 数组存储的数据类型[长度];
- 举例: 定义可以存储3个整数的数组容器,代码如下:
int[] arr = new int[3];
方式二
- 格式:
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素3...};
- 举例: 定义存储1,2,3,4,5整数的数组容器。
int[] arr = new int[]{1,2,3,4,5};
方式三
- 格式:
数据类型[] 数组名 = {元素1,元素2,元素3...};
- 举例: 定义存储1,2,3,4,5整数的数组容器
int[] arr = {1,2,3,4,5};
12.2 数组的访问
- 格式:
数组名[索引]
- 索引访问数组中的元素:
- 数组名[索引]=数值,为数组中的元素赋值
- 变量=数组名[索引],获取出数组中的元素
第十三章 数组原理内存图
13.1 Java虚拟机的内存划分
- JVM的内存划分:
| 区域名称 | 作用 |
|---|---|
| 寄存器 | 给CPU使用,和我们开发无关。 |
| 本地方法栈 | JVM在使用操作系统功能的时候使用,和我们开发无关。 |
| 方法区 | 存储可以运行的class文件。 |
| 堆内存 | 存储对象或者数组,new来创建的,都存储在堆内存。 |
| 方法栈 | 方法运行时使用的内存,比如main方法运行,进入方法栈中执行。 |
13.2 数组在内存中的存储
- 一个数组内存图
public static void main(String[] args) {
int[] arr = new int[3];
System.out.println(arr);//[I@5f150435
}
以上方法执行,输出的结果是[I@5f150435,这个是什么呢?是数组在内存中的地址。new出来的内容,都是在堆内存中存储的,而方法中的变量arr保存的是数组的地址。
输出arr[0],就会输出arr保存的内存地址中数组中0索引上的元素
- 两个数组内存图
public static void main(String[] args) {
int[] arr = new int[3];
int[] arr2 = new int[2];
System.out.println(arr);
System.out.println(arr2);
}
13.3 数组越界异常
观察一下代码,运行后会出现什么结果。
public static void main(String[] args) {
int[] arr = {1,2,3};
System.out.println(arr[3]);
}
创建数组,赋值3个元素,数组的索引就是0,1,2,没有3索引,因此我们不能访问数组中不存在的索引,程序运行后,将会抛出 ArrayIndexOutOfBoundsException 数组越界异常。在开发中,数组的越界异常是不能出现的,一旦出现了,就必须要修改我们编写的代码。
13.4 数组空指针异常
观察一下代码,运行后会出现什么结果。
public static void main(String[] args) {
int[] arr = {1,2,3};
arr = null;
System.out.println(arr[0]);
}
arr = null 这行代码,意味着变量arr将不会在保存数组的内存地址,也就不允许再操作数组了,因此运行的时候
会抛出NullPointerException 空指针异常。在开发中,数组的越界异常是不能出现的,一旦出现了,就必须要修
改我们编写的代码。
13.5 数组获取最大值元素
public static void main(String[] args) {
int[] arr = { 5, 15, 2000, 10000, 100, 4000 };
//定义变量,保存数组中0索引的元素
int max = arr[0];
//遍历数组,取出每个元素
for (int i = 0; i < arr.length; i++) {
//遍历到的元素和变量max比较
//如果数组元素大于max
if (arr[i] > max) {
//max记录住大值
max = arr[i];
}
}
System.out.println("数组最大值是: " + max);
}
13.6 数组反转
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4, 5 };
/*
循环中定义变量min=0最小索引
max=arr.length‐1最大索引
min++,max‐‐
*/
for (int min = 0, max = arr.length ‐ 1; min <= max; min++, max‐‐) {
//利用第三方变量完成数组中的元素交换
int temp = arr[min];
arr[min] = arr[max];
arr[max] = temp;
}
// 反转后,遍历数组
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}