目录
一、Java概述
1.1 Java语言背景
Java语言诞生于1995年,是Sun(Stanford University Network)公司推出的一门计算机语言
公认的Java之父:詹姆斯·高斯林(James Gosling)
1.2 Java语言的三个版本
1.Java SE:Java 语言的(标准版),用于桌面应用的开发,是其他两个版本的基础
2.Java EE:Java 语言的(企业版),用于 Web 方向的网站开发
3.Java ME : Java 语言的(小型版),用于嵌入式消费类电子设备
1.3 Java语言的跨平台原理
常用的操作系统(平台)有哪些:
1.Windows
2.Mac
3.Linux
Java为什么可以跨平台:
1.Java 程序可以在任意操作系统上运行,实现了一次编写,到处运行
2.在需要运行 Java 应用程序的操作系统上,安装一个与操作系统对应的 Java 虚拟机(JVM Java Virtual Machine)即可
3.JVM 虚拟机本身不允许跨平台,允许跨平台的是 Java 程序(我们的代码)
总结:一次编写,到处运行
1.4 JRE和JDK
Java程序开发的三个步骤:
1. 编写代码:书写正确的代码
2. 编译代码:通过javac命令编译java文件,编译成功后,会生成对应的字节码文件
3. 运行代码:通过java命令运行
JDK、JRE和JVM分别是什么?有什么作用?
JDK(Java Develop Kit)是 Java 语言的软件开发工具包,内部包含了代码的编译工具和运行工具
JRE(Java Runtime Environment)指Java运行环境,包含 JVM 虚拟机及 Java 核心类库
JVM(JVM Java Virtual Machine)Java 虚拟机
核心类库:我们自己在编写代码的过程中,需要用到 java 已经写好的这些 java 文件
包含关系:(JDK1.8之后)JDK 包含JRE 包含JVM
1.5 DOS命令
二、Java环境搭建
2.1 环境变量的配置
为什么要配置环境变量:
目的:在计算机中的任意位置,都能访问到bin目录下的javac和java工具
环境变量的配置流程:
第一步:我的电脑右键 - 属性 - 高级系统设置 - 环境变量
第二步:系统变量中:新建变量名为 JAVA_HOME,值为JDK的安装路径
第三步:系统变量中:找到Path,新建变量 %JAVA_HOME%\bin
第四步:依次点击三个[确定],缺一不可!
另一种配置方式:
在Path中直接配置bin目录的[绝对路径]
三、Java基础语法
3.1 注释
什么是注释:对代码解释说明的文字信息,方便程序员阅读代码
注释的分类:
单行注释 //
多行注释 /* 内容 */
文档注释 /** 内容 */
注意:多行注释不能嵌套使用;注释不参与编译和运行!
3.2 关键字(保留字)
什么是关键字:被Java赋予了特殊含义的英文单词
关键字的特点:
1:英文单词纯小写
2:代码编辑器对其有特殊颜色标记
3.3 常量
什么是常量:程序运行过程中,其值不会发生改变的量(数据)
常量的分类:
1.整数常量:-100 200
2.小数常量:5.5 3.14
3.字符常量:'A' '7' '男'
4.字符串常量:"HelloWorld" "肆月廿"
5.布尔常量:值只有true和false
6.空常量:null
3.4 变量
什么是变量:本质是内存中的存储空间,空间中存着经常发生改变的量
定义变量的格式:数据类型 变量名 = 变量值;
范例1:int age = sc.nextInt();
范例2:double price = 99.99;
范例3:boolean result = true;
如何使用变量:使用变量的标识(变量名)
范例1:System.out.println(age);
范例2:System.out.println(price);
范例3:System.out.println(result);
使用变量的注意事项:
注意1:变量名不能重复定义
注意2:一条语句可定义多个变量,中间用逗号分隔
注意3:变量在使用前必须赋值
注意4:定义float类型变量,在数据末尾加F;定义long类型变量,在数据末尾加L
注意5:变量的作用域范围
3.5 数据单元
想要了解数据类型,需要先了解数据在计算机中的大小单元
最小信息单元:bit,比特位,通常用 b 表示
最小的存储单元:byte,字节,通常用 B 表示
一个byte字节,由8个bit位组成
1B(字节) = 8bit、1KB = 1024B、1MB = 1024KB
1GB = 1024MB、1TB = 1024GB、1PB = 1024TB
Java是一门强类型语言,不同数据类型分配了不同的[内存空间],所以他们表示的[数据大小]也不一样
3.6 数据类型
基本数据类型分为 [四类八种]:
1.整型:byte short int(默认) long
2.浮点型:float double(默认)
3.字符型:char
4.布尔型(非数值):boolean
引用数据类型:数组([])、类(class)、接口(interface)..
3.7 标识符
什么是标识符:给类、方法、变量等起名字的符号(由自己定义命名的标识)
标识符的定义规则:
规则1:由数字、字母、_(下划线)、$组成
规则2:不能是Java的关键字
规则3:不能以数字开头
规则4:区分大小写(命名约定:1.小驼峰命名法,用于变量、方法.. 2.大驼峰命名法,用于类)
3.8 键盘录入对象 Scanner
使用步骤:
步骤1:导包 import java.util.Scanner;
步骤2:创建对象 Scanner sc = new Scanner(System.in);
推荐步骤:控制台提示 System.out.println("请输入一个整数:");
步骤3:调用方法,接收数据 int num = sc.nextInt();
注意:自己起的类名,不能和系统已有的类名相同,否则程序会出现错误(例如:Scanner、String、System不可用作自己的类名)
四、类型转换
4.1 隐式转换(自动转换)
类型转换:因为Java中基本数据类型,本质上的区别是数据取值范围大小不一样。那么在操作过程中,会出现赋值、互相转换的过程
隐式转换:也称为自动转换,是将取值范围小的数据,赋值给取值范围大的数据,可以直接赋值(计算机自动完成)
范例1:double d = 10; 范例2:long l = 10;
数据范围从小到大:byte -> short (char) -> int -> long -> float -> double
隐式转换注意细节:
细节1:小的数据类型,和大的数据类型运算,小的会提升为大的之后,再进行运算
细节2:byte、short、char在运算时,不管是否有更高的类型存在,都会自动提升为int类型,然后再参与运算
4.2 强制转换
什么是强制转换:将取值范围大的数据,赋值给范围小的数据
范例1:int a = 5.5; //编译报错 范例2:int b = 10000000L; //编译报错
强转的格式:目标数据类型 变量名 = (目标数据类型) 变量值;
范例1:int a = (int)5.5; //手动书写强转格式
范例2:int b = (int)100000000000L; //手动书写强转格式
注意:强转会造成数据精度的丢失,不建议使用
五、运算符
什么是运算符:对常量或变量进行操作的符号
什么是表达式:用运算符将常量或变量连接起来,并且符合Java语法的式子
[ 1 ] 算数运算符
算数运算符有哪些:
1.加 +
2.减 -
3.乘 *
4.除 /:两数相除,只取商,且只能得到整数,如果想带有小数的结果,必须有小数(浮点数)参与运算
范例1:10 / 3.0 = 3.3333333333333335
范例2:10.0 / 3 = 3.3333333333333335
5.取余 %:两数相除,只取余数
范例:10 % 3 = 10 / 3 = 商3...余1 // 计算机看到是%,只取余数1
字符的+操作
char字符在参与运算时,是怎么提升为int的:对应ASCII码表中10进制的int值
ASCII:美国信息交换标准代码,计算机中[字节]到[字符]的一套对应关系
字符串的+操作
当+号遇到字符串,这时的+号是字符串连接符。字符串可以使用+号和任意类型进行[拼接]
[ 2 ] 自增自减运算符
自增自减运算符有哪些:
++:变量自身+1,可用于变量前、后
--:变量自身-1,可用于变量前、后
变量单独使用和参与操作时的区别:
单独使用:在前在后效果一样
参与操作:
(1)符号在前:先拿变量自增或自减,再拿结果参与操作(先运算再赋值)
(2)符号在后:先拿变量参与操作,然后将结果自增或自减(先赋值再运算)
[ 3 ] 赋值运算符
基本赋值运算符:
= (将等号右边的值,赋给左边的变量)
扩展赋值运算符:
+=、-=、*=、/=、%= (将等号两边的值参与运算,再将结果,赋给左边的变量)
扩展赋值运算符的特点:隐含了强转
[ 4 ] 关系运算符
关系运算符也称为“比较运算符”:
等于 ==、不等于 !=、大于>、大于等于 >=、小于 <、小于等于 <=
关系表达式:含有关系运算符的表达式,称为关系表达式
关系表达式的结果,都是什么类型:结果只能是true和false,都是boolean类型
[ 5 ] 逻辑运算符
逻辑运算符:
与 &:遇false则false
或 |:遇true则true
非 !:取反
异或 ^:相同为false,不同为true
作用:整合多个关系表达式的条件,结果也都是boolean类型
短路逻辑运算符:
短路与 &&:遇fasle则短路(作用上和逻辑运算符结果一样)
短路或 ||:遇true则短路(作用上和逻辑运算符结果一样)
推荐使用短路逻辑运算符,可以提升代码的效率
[ 6 ] 三元运算符
三元运算符的格式:对应数据类型 变量名 = 关系表达式 ? 位置1 : 位置2;
执行流程:判断关系表达式的结果,为true返回表达式1,为false返回表达式2
六、分支结构
6.1 流程控制语句
流程控制语句分为:
1. 顺序结构:默认执行流程
2. 分支结构:if、switch
3. 循环结构:for、while、do..while
顺序结构:是Java程序的默认执行流程,从上到下,从左到右依次执行
作用:通过一些语句,来控制程序(代码)的执行流程
6.2 分支结构 - if语句
格式:if(关系表达式1){
语句体1;
} else if(关系表达式2){
语句体2;
}...else{
//上述表达式都不成立,则走else语句体
}
注意1. 如果if语句所控制的语句体,只有一条语句,可以省略大括号
注意2. if语句的小括号后面,不要写分号,Java中分号代表语句的结束
6.3 分支结构 - switch语句
格式:switch(变量/表达式){ //变量/表达式:将要被匹配的值,取值为byte、short、int、char、枚举(JDK5)、String(JDK7)
case 值: //后面跟的是,要和表达式进行比较的值(被匹配的值)
要执行的语句;
break; //表示中断,结束的意思,用来结束switch语句
…
default: //表示所有情况都不匹配的时候,就执行该处的内容,和if语句的else相似
要执行的语句;
}
执行流程:
1:首先判断表达式的值
2:依次和case后面的常量进行比较
(1)如果有对应的值,执行case后的语句体,在执行过程中遇到break就会结束
(2)如果所有的case后面的值都不能匹配,就会执行default语句体,然后将程序结束掉
switch语句的case穿透
case的穿透是如何产生的:
1.如果switch语句中,case后面省略了break,就会开始穿透
2.开始case穿透,后续的case就不再具有匹配效果,内部语句都会执行;直到再次遇到break停止,或者switch语句执行完毕后停止
6.4 循环结构 - for循环
for循环格式:for( 初始化语句; 判断语句; 控制语句 ){
循环体;
}
for循环执行流程:
1. 执行初始化语句
2. 执行判断语句,看其boolean类型的结果
(1)如果为false则结束循环
(2)如果为true则继续执行
3. 执行循环体语句
4. 执行控制语句
5. 回到第2步继续判断
6.5 循环结构 - while循环
while循环完整格式:初始化语句;
while(判断语句){
循环体;
控制语句;
}
while循环简化格式:while(判断语句){
循环体;
} //多用于死循环
while循环执行流程:
1. 执行初始化语句
2. 执行判断语句,看其boolean类型的结果
3. 执行循环体语句
4. 执行控制语句
5. 回到第2步继续判断
6.6 循环结构 - do...while循环
do..while循环完整格式:初始化语句;
do{
循环体;
控制语句;
}while(判断语句)
do..while循环简化格式:do{
循环体;
}while(判断语句)
三种循环的区别
for:需要先判断条件是否成立,然后决定是否执行循环体语句(先判断,后执行)
while:需要先判断条件是否成立,然后决定是否执行循环体语句(先判断,后执行)
do..while:先执行一次循环体,然后再判断条件是否成立,然后决定是否执行循环体语句(先执行一次循环体,再判断)
for和while循环区别
for循环初始化语句定义的变量,归属于for循环语法结构,所以循环结束后就不能再使用了
while循环初始化语句定义的变量,由于在循环体外定义(main方法中),不归属于while循环体,所以循环结束后还可以使用
应用场景区别
知道循环次数,推荐使用for循环
不知道循环次数,推荐使用while循环
do..while循环很少使用
6.7 死循环
for循环死循环:for( ; ; ){ }
while循环死循环(常用):while( true ){ }
do..while循环死循环:do{ }while( true );
如果使用死循环,需要考虑程序的出口(结束循环的条件)
6.8 跳转控制语句
continue关键字作用:
仅用于循环语句,作用是跳过本次循环,继续下一次循环的执行
break关键字作用:
用于循环语句和分支语句,作用是结束整个循环或者分支
循环标号的使用:
在循环语句的关键字前,起一个"标号名",然后在某种情况下,使用break + 标号名,结束该循环语句
6.9 Random随机数对象
Random的作用:产生一个指定范围内的伪随机数(常用生成整数)
使用步骤:
步骤1:导包 import java.util.Random;
步骤2:创建对象 Random r = new Random();
步骤3:获取随机数 int number = r.nextInt(范围); // 左包含右不包含
(1)范围处填写一个整数,代表指定0到该整数(左包含右不包含)的范围
(2)获取一个min到max之间的随机整数,包含min和max,万能公式:(max - min + 1) +min;
七、数组
7.1 数组的概念及作用
什么是数组:数组(array)是一种容器,可用来存储多个相同类型的数据
建议:数组容器的类型,和存储的数据类型保持一致!
7.2 数组的定义格式
格式1:数据类型[] 变量名
范例:int[ ] arr(推荐使用的格式)
格式2:数据类型 变量名[]
范例:int arr[ ]
7.3 数组动态初始化
Java中的数组(变量)必须先初始化,然后才能使用
初始化:就是在内存中,为数组容器开辟空间,并将数据存入容器的过程
数组动态初始化的格式:
数据类型[] 变量名 = new 数据类型[长度];
范例:int[] arr = new int[5];
//动态初始化了一个数组,数组名是arr,长度为5,该数组能存储5个int类型数据
打印数组变量名会出现什么:
数组的内存地址:
1.[:表示一维数组
2.@:连接符
3.I:int的意思,表示数组中存储的数据类型
4.数字和字母的组合串:该数组16进制的内存地址
7.4 数组元素访问
什么是索引:索引是数组容器中空间的编号,可以用来标识数组中元素的位置
索引的特点:
特点1:从0开始
特点2:索引是连续的
特点3:逐个+1
数组元素访问的格式:
数组名[索引];
范例:arr[0]; // 获取该数组第一个元素
7.5 Java内存图
一个数组内存图
Java中内存分配:
栈内存:方法运行时,进入的内存空间;局部变量也存放于栈内存中
堆内存:new出来的内容进入堆内存,并且会产生地址值
方法区:字节码文件(.class)加载时进入的内存空间
本地方法栈:调用操作系统相关资源
寄存器:交给CPU使用
Java中数据的默认值:
整数:0 浮点数:0.0 布尔:false 字符:空字符 引用数据类型:null
引用数据类型:引用,记录了地址值的变量,所对应的数据类型就是引用数据类型
范例:int[] arr = new int[3];
// 数组的变量就是引用数据类型
两个数组内存图
多个数组指向相同内存图
当多个引用指向相同的内存,如果其中一个引用,改变了内存中的内容,其他引用看到的都是"改变后的内容"
理解:多个人牵同一条狗,任何人对狗的操作都会使其看到操作后狗的样子
7.6 数组静态初始化
数组静态初始化的格式:
数据类型[] 变量名 = new 数据类型[]{元素1, 元素2, ...};
范例:int[] arr = new int[]{1, 2, 3};
简化格式:简化了new int[]的书写
范例:int[] arr = {1, 2, 3}; (推荐使用的格式)
7.7 应用场景
静态初始化:知道数组具体元素(给元素)
动态初始化:不知道具体元素,但是知道数组长度时(给长度)
数组操作的两个常见问题
索引越界异常 ArrayIndexOutOfBoundsException:操作了不存在的索引
空指针异常 NullPointerException:访问的引用类型不再指向堆内存
数组遍历:是指将数组中的所有数据取出来(打印、判断、求和等后续操作)
八、方法
8.1 方法概述
什么是方法:一段具有独立功能的代码块,不调用就不执行
方法有什么好处:可以提高代码的复用性
方法使用须知:
1.方法必须先创建才可以使用(方法定义)
2.方法创建后并不是直接运行的,需要手动调用(方法调用)
8.2 方法的定义和调用
带返回值格式:
public static 返回值类型 方法名(参数列表){ 方法体; return 返回值; }
不带返回值格式:
public static void 方法名(参数列表){ 方法体; }
通用格式:
修饰符 返回值类型 方法名(参数类型 参数名1,参数类型 参数名2,......){
方法体;
return 返回值;
}
如果调用了一个没有定义的方法:程序会报错
方法没有被调用:在方法区
方法被调用时加载到了哪里:栈内存
栈内存:栈内存特点是先进后出,后进先出(子弹匣子)
8.3 带参数方法的定义和调用
注意事项:
1. 参数中的数据类型与变量名都不能缺少,否则程序报错
2. 多个参数之间使用逗号分隔
3. 调用带参数的方法时,参数的数量、类型必须与方法定义中设置的匹配,否则程序报错
形参和实参
什么是形参:形式参数,是指方法定义时的参数;作用是接收实参
什么是实参:实际参数,是指方法调用时的参数;也就是实际参与运算的数据,由调用者指定
8.4 带返回值方法的定义和调用
为什么要有带返回值的方法:我们经常会根据一个方法产出的结果,去组织另一段代码逻辑,为了拿到这个方法产生的结果,就需要定义带返回值的方法
return关键字的作用:返回返回值(并且停止方法)
注意事项:
1. return后面的返回值,与方法定义上的数据类型要匹配,否则报错
2. 方法的返回值通常会使用变量接收,否则该返回值将无意义
方法通用定义格式
方法定义时的两个明确:
明确1:返回值类型
该方法需不需要返回一个结果? 它是什么类型的? 如果不需要返回一个结果,在返回值类型处写void
明确2:参数列表
该方法执行过程中,需不需要原材料(实际参与运算的数据),如果需要,写在参数列表中,由数据和变量名组成;有多个参数,使用逗号分隔;如果不需要则不写
8.5 方法的注意事项
定义方法时:
1:参数中的数据类型与变量名都不能缺少,否则程序报错
2:多个参数之间使用逗号分隔
3:方法不能嵌套定义
4:return后面的返回值与方法定义上的数据类型要匹配,否则报错
5:方法的返回值为void,表示该方法没有返回值,可以省略return不写
6:return的作用是返回返回值,并且停止方法;所以return语句下面不能编写代码,属于无效语句会报错
调用方法时:
1:调用带参数的方法时,参数的数量、类型必须与方法定义中设置的匹配,否则程序报错
2:如果调用了一个有返回值的方法,需要用相同类型变量接收,否则返回值将无意义
方法调用的三种方式:
1. 直接调用:用于调用没有返回值的方法(如果调用有返回值的方法,那么将无意义)
2. 赋值调用:必须调用有返回值的方法(将返回值使用相同类型变量接收,用于后续操作)
3. 打印调用:必须调用有返回值的方法(在输出语句中调用方法,相当于直接打印了返回值)
8.6 方法的重载
方法重载的概念:在同一个类中,出现了方法名相同,参数列表不同(数量、类型、顺序)的方法,我们称这些方法构成了重载;方法的重载与返回值无关
方法重载的好处:不用记忆过多繁琐的方法名
8.7 方法的参数传递
传递基本类型:传递的是“记录的具体数值”,形参的改变,不会影响实参
传递引用类型:传递的是“地址值”,形参的改变,会影响实参
8.8 Debug
Debug 介绍与操作流程:
Debug:是供程序员使用的程序调试工具,它可以用于查看程序的执行流程,也可以用于追踪程序执行过程来调试程序
Debug调试又称为断点调试:断点就是一个标记,告诉Debug从标记的位置开始查看
Debug操作流程:
1.打断点:在代码行号后面,点击出一个小红点,开启Debug运行模式后,从标记的地方开始查看
2.在代码区域右键,单击Debug执行即可
3.看Debugger窗口
(1)Frames:看代码运行到哪里了
(2)Variables:看代码执行过程中变量的变化
4.看Console窗口:看代码执行过程中的结果展示,可以录入要录入的数据
5.点Step Into 这个箭头下一步
6.点Stop结束
7.选择要删除的断点,单击鼠标左键即可,或者批量删除
九、进制
9.1 进制的介绍与书写格式
进制:指进制位,是人们规定的一种进位方式
常见进制:
二进制:数据使用0和1表示,逢二进一,借一当二(0b开头,b大小写均可)
八进制:由0到7八个数字组成,逢八进一(0开头)
十进制:逢十进一,借一当十(Java中数值默认是10进制,不需要修饰)
十六进制:由0到9,a到f组成,其中a到f表示10到15,字母大小写均可(0x开头,x大小写均可)
任意进制到十进制的转换:系数*基数的权次幂相加
系数:每一位上的数据本身,不带进制标识
基数:几进制转换,基数就是几
权:从右朝左,0开始逐个+1
十进制到任意进制的转换:除基取余法
使用源数据,不断的除以基数(几进制转换,基数就是几)得到余数,直到商为0,再将余数【倒着拼接】起来即可
9.2 快速进制转换法
8421码:又称BCD码,是BCD码中最常用的一种
BCD: (Binary-Coded Decimal) 二进制码十进制数在这种编码方式中,每一位二进制值的1都是代表一个固定数值,把每一位的1代表的十进制数加起来,得到的结果就是它所代表的十进制数
二进制,快速转十进制:
128 - 64 - 32 - 16 - 8 - 4 - 2 - 1
将二进制的值,从左边套入其中,0对应的值不取,1对应的值取出来相加即可
二进制,快速转八进制:
将三个二进制位看为一组,分别套入上述公式,将结果拼接(注意不是加)
原因:八进制逢八进一,三个二进制位最多可以表示111,也就是数值7(套入上条公式),如果出现第四位,就超范围了
二进制,快速转十六进制:
将四个二进制位看为一组,如果不够使用0补位,分别套入上述公式,将结果拼接(注意不是加)
原因:十六进制逢十六进一,四个二进制位最多可以表示1111,也就是数值15,如果出现第五位,就超范围了
9.3 原码 反码 补码
计算机中的数据,都是以二进制补码的形式在运算,而补码则是通过反码和原码推算出来的
原码:给人看的,可通过8421码,推算出具体数值
就是二进制定点表示法,即最高位为符号位,0表示正,1表示负,其余位表示数值的大小
反码:转换的桥梁
正数的反码与其原码相同,负数的反码是对其原码逐位取反,但符号位除外
补码:计算机底层运算使用补码,也就是真正做运算的
9.4 位运算
基本位运算符
什么是位运算:
是二进制位的运算,需要先将十进制数转为二进制后,再进行运算
在二进制位运算中1和0表示什么:1表示true,0表示false
位运算符:
& 位与:将十进制数转为二进制后竖式运算,遇false则false,遇0则0
| 位或:将十进制数转为二进制后竖式运算,遇true则true,遇1则1
^ 位异或:将十进制数转为二进制后竖式运算,相同为false,不同为true
~ 取反:将十进制数转为二进制后竖式运算,全部取反,0变1,1变0(包括符号位)
异或运算符的特点:
一个数被另一个数,异或两次,该数本身不变
位移运算符
<< 有符号左移:二进制位向左移动,符号位丢弃,右边补齐0
运算规律:向左移动几位,就是乘以2的几次幂
>> 有符号右移:二进制位向右移动,使用符号位进行补位
运算规律:向右移动几位,就是除以2的几次幂
>>> 无符号右移:无论符号位是0还是1,都补0
几乎没什么使用场景
十、二维数组
10.1 二维数组概述
什么是二维数组:用于存储一维数组的数组(容器)
10.2 二维数组动态初始化
二维数组的定义格式:
格式1:数据类型[] [] 数组名(常用)
格式2:数据类型 数组名[] []
格式3:数据类型[] 数组名 []
动态初始化格式:
数据类型 数组名[] [] = new 数据类型[m] [n];
m表示:该二维数组可以存放几个一维数组
n表示:每个一维数组可以存放多少个元素
10.3 二维数组访问元素的细节问题
(1)二维数组中存储的都是一维数组,可以将创建好的一维数组直接存入(存入的是一个一个一维数组的内存地址),存储完成后,增加其中一维数组的元素(增加长度),程序不会报错
(2)如果使用动态初始化创建二维数组,就不能在后期,改变其中一维数组的长度了
10.4 二维数组静态初始化
静态初始化格式:
数据类型 数组名[][] = new 数据类型[][] {{元素1,元素2,元素3 ..} , {元素1,元素2,元素3 ..}};
简化格式:省略书写 new 数据类型[][]
范例:int[][] arr = {{11,22,33},{44,55,66}};
十一、面向对象基础
11.1 面向对象的三大特征是什么
封装、继承、多态
11.2 类和对象
面向对象和面向过程的思想对比
两种思想的区别:
面向过程 POP:是一种以[过程]为中心的编程思想,功能的每一步,都是自己实现的
面向对象 OOP:是一种以[对象]为中心的编程思想,通过指挥对象实现具体的功能
面向对象是基于面向过程的
类和对象的关系
什么是类:类是对现实生活中,一类具有共同属性和行为的事物的抽象
类的组成有哪些:类由属性和行为组成
属性:该类事物所具有的共同特征 (成员变量)
行为:该事物存在的功能,能做的事情 (成员方法)
什么是对象:是看得见,摸得着的真实存在的物体
类是对事物也就是对象的一种描述,可以将类理解为一张设计图,根据设计图,可以创建出具体存在的事物
小结1、客观存在的任何一种事物,都可看做为程序中的对象(万物皆对象)
小结2、使用面向对象思想可以将复杂问题简单化
小结3、将我们从执行者的位置,变成了指挥者
类的定义
类的属性和行为,在代码中通过什么体现:
属性:成员变量(类中方法外的变量)
行为:成员方法(和前面学习的方法相比不带static关键字)
定义一个类的步骤:
步骤1、创建Java文件 编写类名
步骤2、编写类的 成员变量
步骤3、编写类的 成员方法
类创建完成后,不能直接右键运行:
因为我们没有提供main方法,我们需要再创建一个测试类,在测试类中先创建对象,再进行测试
对象的创建和使用
如何创建对象:
格式:类名 对象名 = new 类名();
范例:Student stu = new Student();
注意:类名就是对象的[数据类型]
如果我们打印一个对象名,控制台会打印该对象的内存地址:
全类名(包名+类名)@十六进制内存地址
11.3 对象内存图
单个对象内存图
new出来的对象:在堆内存开辟空间
成员变量:有默认初始化值
两个对象内存图
当出现多次new的动作时,字节码文件不会多次加载:
我们通常使用一张"设计图",就可以创造出多个"对象"
两个引用指向同一个对象内存图
对象类型的变量,是什么类型的数据:
引用类型
对象类型的变量,记录了什么:
记录了该对象的内存地址
垃圾回收:当堆内存中,对象和数组产生的地址,通过任何方式都不能被找到后,就会被判定为内存中的"垃圾",垃圾会被"Java垃圾回收器"在空闲时间自动进行清理
11.4 成员变量和局部变量
成员变量和局部变量的区别:
区别1、类中位置不同
成员变量:类中方法外
局部变量:方法内或方法声明上
区别2、内存中位置不同
成员变量:堆内存(跟随对象走,对象是new出来的进堆)
局部变量:栈内存(跟随方法进栈)
区别3、生命周期不同
成员变量:随对象的存在而存在,随对象的消失而消失
局部变量:随方法的调用而存在,随方法的弹栈而消失
区别4、初始化值不同
成员变量:有默认初始化值
局部变量:没有默认初始化,必须先定义赋值,再使用
十二、封装
12.1 什么是封装
隐藏实现细节,仅对外暴露公共的访问方式
封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。
封装常见的体现
体现1、私有成员变量,并对外提供getXxx()、setXxx()方法
体现2、将代码,抽取到方法中,这是对代码的一种封装
体现3、将属性,抽取到类中,这是对数据的一种封装
封装的好处:
好处1、提高了代码的 安全性
好处2、提高了代码的 复用性
12.2 private关键字
什么是private关键字:
private,私有的意思,是一个权限修饰符,可修饰成员(成员变量、成员方法)
private关键字的特点:
被private修饰的成员,只能在本类中被访问
被private修饰的成员变量,可能被其他类使用,所以我们在本类中,需要提供public修饰的getXxx()、setXxx()方法,让其他类操作私有的成员
private关键字的使用
(不完全)标准类的编写
要求1、将所有成员变量使用private修饰
要求2、提供对应的getXxx()、setXxx()方法
12.3 this关键字
this关键字的作用:
作用1、可以调用本类的成员变量、成员方法
this.成员变量
this.成员方法
作用2、解决局部变量和成员变量重名问题
理解:方法被哪个对象调用,方法中的this就代表哪个对象!
十三、构造方法
13.1 什么是构造方法
什么是构造方法:
创建对象时,所调用的方法
13.2 构造方法的格式特点
特点1、方法名与类名相同
特点2、没有返回值,连void都没有
特点3、没有具体的返回值(不能由return带回结果数据)
执行时机是什么时候:
创建对象时候会自动调用。每创建一次对象,就会执行一次构造方法(注意不能手动调用构造方法)
构造方法的作用:
创建对象,给对象的数据进行初始化
构造方法的注意事项:
注意1、如果没有定义构造方法,系统会给一个默认空参构造(父类哪里继承来的)
注意2、如果定义了构造方法,系统就不会提供默认构造方法了(所以以后定义类时,空参带参都提供)
13.3 空参构造和带参构造的区别
与类名相同 有参数的是带参构造 无参数的是空参构造
注意:
1.如果在创建对象时不写参数,调用的就是无参的构造方法。可是如果你写的有有参的构造方法,而没有无参的构造方法,那么再“创建对象时不写参数”就会报错,程序会认为你知道该怎么做。
2.如果构造方法有参数,在创建对象时传入了参数,那么就会调用此方法,这一点和重载类似。
空参构造的作用是:实例化一个对象
带参构造的作用是:初始化类中的属性
十四、字符串
14.1 API
API:application应用 programing编程 interface接口
API概述 - 帮助文档的使用
什么是帮助文档:
一些定义好的类的使用说明文档(理解为字典)
帮助文档的查看流程:
查看1、当前类所在的包(继承体系)
查看2、基本介绍
查看3、构造方法(创建对象)
查看4、成员方法(常用方法)
14.2 键盘录入字符串
Scanner的哪些方法可以获取控制台录入的字符串:
方法1、next() 结束标识是空格键、tab键
方法2、nextLine() 结束标识是回车键
14.3 String
String概述
java.lang包下的类的使用特点:使用时,不需要导包
字符串对象一旦创建,对象的内容是否可以更改:
不可以(字符串是常量,底层被final修饰)
String类常见构造方法
打印String的变量名,会不会打印对象的内存地址值:
不会,而是打印了该字符串对象所记录的内容
创建String对象的四种方式
方式1、public String() 创建一个空白字符串对象
方式2、public String(char[] chs) 根据字符数组的内容,创建字符串对象
方式3、public String(String original) 根据传入的字符串内容,创建新的字符串对象
方式4、String s = "abc"; 直接赋值的方式创建
创建String对象的区别和对比:
==比较基本类型,和引用类型的区别:
情况1、比基本类型:比的是数据[具体值]
情况2、比引用类型比的是[地址值]
构造方法和双引号创建字符串对象,有什么区别:
使用""创建的字符串:
只要字符序列相同(顺序和大小写),无论在程序中出现几次,JVM都只会建立一个String对象,并在字符串常量池中维护
结论:使用""创建的String对象,在字符串常量池
new出来的字符串:
每一次new都会在堆内存申请新的内存空间;就算内容相同,但是地址不同
结论:使用new创建的String对象,在堆内存
当使用双引号创建字符串对象时,系统会检查该对象,在字符串常量池中是否存在:
存在,则不会重新创建,直接拿来使用
不存在,则创建
字符串常量池,在JDK7版本开始,从方法区中挪到了堆内存
String特点
字符串对象有哪些特点:
特点1:Java程序中所有双引号引起来的内容,都是String类的对象
特点2:字符串内容不可变,它们的值在创建后不能被更改(在底层被final修饰,所以它是一个常量)
特点3:虽然String的内容不可变,但是可以被共享(结合常量池理解:如果使用""创建String,系统会检测常量池中有没有相同内容的,如果有相同内容的,直接拿来使用)
特点4:String在java的lang包下,使用时不需要导包
当字符串使用+号拼接时,底层是怎么执行的:
系统底层会自动创建一个StringBuilder对象,然后调用其append方法完成拼接,再将拼接的结果,调用toString方法转换为String对象
Java常量优化机制:
如果是常量"a"+"b"+"c",那么在编译时,就会将它们拼接为"abc"。由于内容一样,且都是通过双引号创建,所以在内存中维护的是同一个对象
String方法小结:
boolean equals(Obj obj); 比较字符串内容,严格区分大小写
boolean equalsIgnoreCase(Obj obj); 比较字符串内容,忽略大小写
int length(); 返回字符串长度
char charAt(int index); 返回指定索引处的char值
char[] toCharArray(); 将字符串拆分为一个字符数组并返回
String substring(int 开始索引, int 结束索引); 根据传入的两个索引,左包含右不包含地截取,并返回新的字符串
String substring(int index); 从传入的索引截取到字符串末尾 ,并返回新的字符串
String replace(被替换的子串, 新的子串); 使用新值替换字符中所有旧值,并返回新的字符串
String[] split(String "标识"); 根据传入的标识切割字符串,返回字符串数组
14.4 StringBuilder
StringBuilder 概述
StringBuilder:
是一个可变的字符串类,我们可以将它看做是一个用来操作字符串对象的容器
StringBuilder的作用:
提高字符串操作的效率
System.currentTimeMillis();
可以获取当前系统时间的毫秒值
StringBuilder 构造方法
构造1、空参构造
StringBuilder sb = new StringBuilder();
创建一个空的sb对象
构造2、带参构造
StringBuilder sb = new StringBuilder("肆月廿");
根据传入的字符串,创建一个可变的字符串对象(也就是sb对象)
StringBuilder 常用的成员方法
常用方法1、public StringBuilder append(任意类型); 拼接数据,并返回对象本身
常用方法2、public StringBuilder reverse(); 返回相反的字符序列
常用方法3、public int length(); 返回长度(字符出现的个数)
常用方法4、public String toString(); 将当前的sb对象转换为String对象
StringBuilder 提高效率的原理
字符串使用+号拼接,堆内存会有什么现象?
一个+号创建了两个对象(一个sb一个String)
String和StringBuilder的区别?
String创建出来内容不可变,StringBuilder内容可变
十五、集合
15.1 什么是集合
提供一种存储空间可变的存储模型,存储的数据容量可以发生改变
通常,我们的Java程序需要根据程序运行时才知道创建了多少个对象。但若非程序运行,程序开发
阶段,我们根本不知道到底需要多少个数量的对象,甚至不知道它的准确类型。为了满足这些常规
的编程需要,我们要求能在任何时候,任何地点创建任意数量的对象,而这些对象用什么来容纳
呢?我们首先想到了数组,但是!数组只能存放同一类型的数据,而且其长度是固定的,那怎么办
了?集合便应运而生了
15.2 集合和数组的区别对比
共同点:都是存储数据的容器
不同点:数组容量固定,集合容量可变
15.3 ArrayList构造方法和添加方法
如何创建一个集合对象:
ArrayList list = new ArrayList(); //不完整格式
ArrayList<泛型> list = new ArrayList<>();
如果不指定集合泛型,那么集合可以存储多个不同类型数据,但是这样的需求少之又少,所以创建集合对象我们需要指定泛型
泛型的作用:
对集合存储的类型的数据进行限制(只能填写引用数据类型)
集合如要存基本数据类型,泛型需怎么写:
要写基本类型对应的包装类(引用类型)
除了int的包装类是Integer,char的包装类是Character这两个特殊,其余都是首字母大写(Byte、Short、Long、Float、Double、Boolean)
集合的添加方法
boolean add(E e); 将指定元素追加到集合末尾
boolean add(int index, E e); 将指定元素插入到指定索引处
ArrayList常用成员方法
boolean remove(Obj o); 删除指定的元素,返回是否删除成功
E remove(int index); 根据索引删除元素,返回被删除的元素
E set(int index, E e); 修改指定索引处的元素,返回被修改的元素
E get(int index); 返回指定索引处的元素
int size(); 返回集合中元素个数