java
cnblogs 2024-07-30 08:09:01 阅读 92
第一章 java概念和开发注意事项
java特点
- Java语言是面向对象的(oop)
- Java语言是健壮的。java的强类型机制、异常处理、垃圾的自动收集等是Java程序健壮性的重要保证
- Java语言是跨平台性的 [即:一个编译好的.class 文件可以在多个系统下运行,这种特性称为跨平台] 根本原因是JVM是java虚拟机 解释和执行是靠JVM,包含在JDK
- Java语言是解释型的[了解]->解释性语言:javascript,PHP java 编译性语言:c/c++
- 区别是:解释性语言,编译后的代码,不能直接被机器执行,需要解释器来执行,编译性语言编译后的代码,可以直接被机器执行,c/c++
java的安装过程
什么是JDK,JRE
● JDK 基本介绍
1.JDK 的全称(Java Development Kit Java开发工具包)
JDK=JRE +iava的开发工具[iava,javac,iavadoc,javap等]
2.JDK是提供给Java开发人员使用的,其中包含了java的开发工具,也包括了JRE所以安装了JDK,就不用在单独安装JRE了。
● JRE 基本介绍
1.JRE(ava Runtime EnvironmentJava运行环境)
JRE = JVM +Java的核心类库[类]
2.包括Java虚拟机(JVM Java Virtual Machine)和Java程序所需的核心类库等如果想要运行一个开发好的Java程序,计算机中只需要安装JRE即可:
编译过程
1.有了java源文件,通过编译器将其编译成JVM可以识别的字节码文件
2.在该源文件目录下,通过javac编译工具对Hello.java文件进行编译。
如果程序没有错误,没有任何提示,但在当前目录下会出现一个Hello.class文件该文件称为字节码文件,也是可以执行的java的程序。
开发注意事项和细节
1.Java源文件以 .java 为扩展名。源文件的基本组成部分是类(class),如本类中的Hello类。
2.Java应用程序的执行入口是main()方法。它有固定的书写格式:public static void main(Stringll args) {...}
3.Java语言严格区分大小写。
4.Java方法由一条条语句构成,每个语句以“;”结束。
5.大括号都是成对出现的,缺一不可。[习惯,先写 {} 再写代码]
6.-个源文件中最多只能有一个public类。其它类的个数不限。[演示],编译后,每一个类,都对于一个.class
7.如果源文件包含一个public类,则文件名必须按该类名命名!
8.一个源文件中最多只能有一个public类。其它类的个数不限,也可以将main方法写在非public类中,然后指定运行非public类,这样入口方法就是非public的main方法,就是把其他非public的类当主类运行
如何掌握新知识点
1.学习新技术和知识点不要考虑细节,能使用就行
2.传统技术和新技术有什么优点
4.crud在工作上基本能搞定
5.开始研究技术细节,最后研究这个,没有之境
java转义字符
在控制台,输入 tab 键,可以实现命令补全
第一个\是转移 \\ 输出两个一个是转义字符
\t :一个制表位,实现对齐的功能 (固定宽度)
\n :换行符
\ :一个\
" :一个"
' :一个' \r :一个回车 System.out.println("韩顺平教育\r)
转移字符使用:System.out.println("北京\t 天津\t 上海");
文档注释
javadoc -d 文件名 生成的文件在这里
代码规范
常用的DOS(命令)
1.查看当前目录是有什么内容 dir
dir dir d:\abc2\test200
2.切换到其他盘下:盘符号 cd : change directory
案例演示:切换到 c 盘 直接 c: 更目录下切换
3.切换到当前盘的其他目录下 (使用相对路径和绝对路径演示), ..\表示上一级目录
案例演示: cd d:\abc2\test200 cd ....\abc2\test200
4.切换到上一级: cd ..
5.切换到根目录:cd
6.查看指定的目录下所有的子级目录 tree
7.清屏 cls
8.退出 DOS exit
路径讲解
\ 根目录就是最顶的目录 也可以理解为D盘 绝对路径
Java API 文档
第二章 变量
变量的注意事项
1.变量表示内存中的一个存储区域[不同的变量,类型不同,占用的空间大小不同比如:int4 个字节,double 就是 8个字节,先有基本印象,后面说字节]
2.该区域有自己的名称[变量名]和类型[数据类型]
3.变量必须先声明,后使用,即有顺序
4.该区域的数据/值可以在同一类型范围内不断变化
5.变量在同一个作用域内不能重名
6.变量=变量名+值+数据类型,这一点请大家注意。变量三要素
程序中加号的使用
1.当左右两边都是数值型时,则做加法运算
2.当左右两边有一方为字符串,则做拼接运算
3.运算顺序,是从左到右
数据类型
String在java不是基本数据类型 它是一个类
引用类型都是地址
整数类型
整数类型的使用细节
浮点类型
浮点类型使用细节
5.12e2 = 5.12x100 e = 10的2次方 e-2 10的负二次
浮点数陷阱:8.1 / 3 = 2.69999997 计算机存储的时候是以精度来存储的,计算机问题,计算结果时以精度来返回这个值
8.1有可能是后面8.100001计算机不知道后面有什么
重要点: 当我们对运算结果是小数的进行相等判断,要小心
解决方法:应该是以两个数的差值的绝对值,两个数相减得到的,在某个精度范围类判断
字符类型
char类型 直接赋值数字的话,输出是对应的ascll
字符类型的使用细节
注意:转义字符和普通字符一样,都是占用一个字节的空间。合起来 表示一个转义字符,
强制转换输出是对应的数字,
例如:a输出97, char类型也可以运行,例如:char a = 'a'+10 println(a) 这里是char类型输出,
println('a'+10) 这里和整数运算 输出是数字
println默认打印的是整形,但是可以用printf格式化打印
字符类型的本质探讨 (面试或测试)
布尔类型(boolean)
使用细节:不可以0或非 0的整数替代false和true,这点和C语言不同
基本数据类型转换
自动类型转换
自动类型转换和细节
计算后是int类型 只要运算了就是int
boolean类型不参与转换,要是赋值给其它类型会报错
字符串转int之类的返回即可
强制类型转换
介绍
自动类型转换的逆过程,将容量大的数据类型转换为容量小的数据类型。使用时要加上强制转换符(),但可能造成精度降低或溢出,格外要注意。
注意与细节
第三点,意思是精度int比char大
强制类型使用方式: (类型)操作数
基本数据类型和String类型的转换
注意:类似String c1 = "zzbc",转不了int类似的类型,可以看函数的介绍
**println打印函数也是 一旦 "" + 这样结合就是基本类型转String类型了 看+号两边数值做加法运算,两边 有一方是字符串就是拼接运算
注意事项
1.在将String 类型转成 基本数据类型时,要确保String类型能够转成有效的数据,比如:我们可以把"123",转成一个整数,但是不能把 "hello" 转成一个整数
2.如果格式不正确,就会抛出异常,程序就会终止,这个问题在异常处理章节中,会处理
第三章 运算符
算术运算符
算术运算符是对数值类型的变量进行运算的,在Java程序中使用的非常多
注意:
1). double d=10/4; java中先10/4=2, 然后double =>2.0 double d=10.0/4; 里面就是double运算了,精度提升double转换
2). 取模 在%的本质 公式:a%b = a - a / b * b
3). 前++和后++: 作为独立的语句使用 前++和后++都完全等价于i=i+1,作为表达式使用前++:++i先自增后赋值, 后++:i++先赋值后自增
代码思路分析:1.需求,2思路分析,3.代码
关系运算符
(1)关系运算符的结果都是boolean型,也就是要么是true,要么是false
(2)关系表达式 经常用在 if结构的条件中或循环结构的条件中
逻辑运算符
用于连接多个条件(多个关系表达式)最终的结果也是一个boolean值
说明逻辑运算规则
1). a&b : & 叫逻辑与:规则:当 a 和 b 同时为 true ,则结果为 true, 否则为 false
2). a&&b : && 叫短路与:规则:当 a 和 b 同时为 true ,则结果为 true,否则为 false
3). a|b : | 叫逻辑或,规则:当 a 和 b ,有一个为 true ,则结果为 true,否则为 false
4). a||b : || 叫短路或,规则:当 a 和 b ,有一个为 true ,则结果为 true,否则为 false
5). !a : 叫取反,或者非运算。当 a 为 true, 则结果为 false, 当 a 为 false 是,结果为 true
6). a^b: 叫逻辑异或,当 a 和 b 不同时,则结果为 true, 否则为 fals
赋值运算符
细节:
1 运算顺序从右往左 int num = a + b + c; (这里说的是 等号的右边)
2 赋值运算符的左边 只能是变量,右边 可以是变量、表达式、常量值
int num = 20; int num2= 78 * 34 - 10; int num3 = a;
3 复合赋值运算符等价于下面的效果
比如:a+=3;等价于 a=a+3; 其他类推
4 复合赋值运算符会进行类型转换。
byte b = 2; b+=3; b++ 等价 b = (byte)(b +2) 直接 b = b + 3 就会报错精度提高了,
三元运算符
运算符的优先级
标识符的命名规则和规范
标识符的概念
标识符规范
1.包名:多单词组成时所有字母都小写:aaa.bbb.ccc //比如 com.hsp.crm
2.类名、接口名:多单词组成时,所有单词的首字母大写:XxxYyyZzz [大驼峰]
比如: TankShotGame
3.变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写:xxxYyyZzz [小
驼峰, 简称 驼峰法]
比如: tankShotGame
4.常量名:所有字母都大写。多单词时每个单词用下划线连接:XXX_YYY_ZZZ
比如 :定义一个所得税率 TAX_RATE
5.后面我们学习到 类,包,接口,等时,我们的命名规范要这样遵守,更加详细的看文档.
关键字保留字
保留字:Java 保留字:现有 Java 版本尚未使用,但以后版本可能会作为关键字使用。自己命名标识符时要避免使用这些保留
字 byValue、cast、future、 generic、 inner、 operator、 outer、 rest、 var 、 goto 、const
进制
进制介绍:
对于整数,有四种表示方式:
二进制:0,1 ,满 2 进 1.以 0b 或 0B 开头。
十进制:0-9 ,满 10 进 1。
八进制:0-7 ,满 8 进 1. 以数字 0 开头表示。
十六进制:0-9 及 A(10)-F(15),满 16 进 1. 以 0x 或 0X 开头表示。此处的 A-F 不
键盘输入语句
介绍:在编程中,需要接收用户输入的数据,就可以使用键盘输入语句来获取。Input.java , 需要一个 扫描器(对象), 就是
Scanner
步骤 :
1.导入该类的所在包, java.util.*
2.创建该类对象(声明变量)
3.调用里面的功能
4.System.in 代表从键盘输入
读取字符串的某一个:怎么把字符串转成字符char-> 含义是指把字符串的第一个字符得到,s5.charAt(0)得到 s5 字符串的第一个字符'1'
第四章 程序控结构
程序流程控制介绍
- 顺序控制 程序从上到下逐行地执行,中间没有任何判断和跳转。
- 分支控制
- 循环控制
顺序控制
程序从上到下逐行地执行,中间没有任何判断和跳转。
分支控制
1 单分支 if
2 双分支 if-else
3 多分支 if-else if -....-else
单分支:
双分支:
多分支:
switch分支
只要是有值返回的都是表达式
switch流程图:
switch细节
Double不能当返回值
思路:要是有double类型的必须要用switch语句 当表达式那就 强制转换即可
可以强制转换
switch和if的比较
1 如果判断的具体数值不多,而且符合 byte、 short 、int、 char, enum[枚举], String 这 6 种类型。虽然两个语句都可
以使用,建议使用 swtich 语句。
2 其他情况:对区间判断,对结果为 boolean 类型判断,使用 if,if 的使用范围更广
循坏控制
for循坏
基本语法:
124可以随便写注意运行顺序即可 且可以用逗号运算符(自己之前学的)
运行顺序:for(1;2;4){3}
for循坏的注意事项和细节说明
1 循环条件是返回一个布尔值的表达式
2 for(;循环判断条件;) 中的初始化和变量迭代可以写到其它地方,但是两边的分号不能省略。
3 循环初始值可以有多条初始化语句,但要求类型一样,并且中间用逗号隔开,循环变量迭代也可以有多条变量迭代
语句,中间用逗号隔开。
循坏条件最终必须返回一个 ture或false
for(;;)配合break语句 使用很好
编程思路
打印 1~100 之间所有是 9 的倍数的整数,统计个数 及 总和.[化繁为简,先死后活]
1 化繁为简 : 即将复杂的需求,拆解成简单的需求,逐步完成(先完成简单的需求,后在完成其他的,拆解) 编程 = 思想 --练习-> 代码
2 **先死后活 **: 先考虑固定的值,然后转成可以灵活变化的值 (可以设定个比较小的值,后计算,后面在改变量)
思路分析: (先写固定值 后在改)
打印 1~100 之间所有是 9 的倍数的整数,统计个数 及 总和
化繁为简(一步一步来)
(1) 完成 输出 1-100 的值 拆解
(2) 在输出的过程中,进行过滤,只输出 9 的倍数 i % 9 ==0
(3) 统计个数 定义一个变量 int count = 0; 当 条件满足时 count++;
(4) 总和 , 定义一个变量 int sum = 0; 当条件满足时累积 sum += i;
while循坏
while的注意事项
循环条件是返回一个布尔值的表达式
while循环是先判断再执行语句
do while 循坏
多重循坏控制(重点)
1 将一个循环放在另一个循环体内,就形成了嵌套循环。其中,for ,while ,do…while 均可以作为外层循环和内层循环。
【建议一般使用两层,最多不要超过 3 层, 否则,代码的可读性很差】
2 实质上,嵌套循环就是把内层循环当成外层循环的循环体。当只有内层循环的循环条件为 false 时,才会完全跳出内
层循环,才可结束外层的当次循环,开始下一次的循环
3 设外层循环次数为 m 次,内层为 n 次,则内层循环体实际上需要执行 m*n
跳转语句break
break出现在循环体中的switch语句体内时,起作用只是跳出该switch语句体,并不能终止循环体的执行。若想强行终止循环体的执行,可以在循环体中,但并不在switch语句中设置break语句,满足某种条件则跳出本层循环体。
流程:
细节和注意事项
continue跳转语句
continue语句用于循环语句中,作用是不执行循环体剩余部分,直接进行下次循环。
if continue的作用:会跳过当前循环中的代码,强迫开始下一次循环。可以理解为如果没 判断语句就一直进入这个continue就一直跳过,如果 有if就指定跳过
return
介绍:
return使用在方法,表示跳出所在的方法,在讲解方法的时候,会详细的介绍
这里我们简单的提一下。
注意:如果 return 写在 main方法,退出程序..
第五章 数组、排序和查找
数组介绍
数组可以存放多个同一类型的数据。数组也是一种数据类型,是引用类型
数组的使用
使用方法动态初始化1:
把三个int数组 传给a a肯定也是数组来的
数组的引用就是数组的使用,访问,获取
数组名[下标/索引]
动态初始化2
先声明 -> int i[]; 在创建i = new int[10] 先声明数组,再 new 分配空间
静态初始化
值分配好的
数组的注意事项
1.这里也满足自动类型转换
数组赋值机制
1 基本数据类型赋值,这个值就是具体的数据,而且相互不影响。
int n1 = 2; int n2 = n1;
2 数组在默认情况下是引用传递,赋的值是地址 传递地址
地址在堆这边
排序
排序是将一群数据,依指定的顺序进行排列的过程。排序的分类:
1.内部排序:指将需要处理的所有数据都加载到内部存储器中进行排序。包括(交换式排序法、选择式排序法和插入式排序法);
2.外部排序法:数据量过大,无法全部加载到内存中需要借助外部存储进行排序。包括(合并排序法和直接合并排序法)。
冒泡排序
冒泡排序(Bubble Sorting)的基本思想是:通过对待排序序列从后向前(从下标较大的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就象水底下的气泡一样逐渐向上冒。
解析:
冒泡排序:
两个相邻数 比较,把最大的放后面即可,每一次排序最大的数会在最后面,所以每次排序后,减少一次比较即可 ,
相关代码:
多维数组 - 二维数组
length二维数组的使用:
二位数组中,如果直接调用b.length方法,返回的则是b数组的行数,
如果是b[0].length方法则返回的是0行所代表的长度。
内存布局
注意:数组名指向第一行的首元素
二维数组的使用 方式
动态语法1:
1.类型[][] 数组名=new 类型[大小][大小]
2 比如: int a[][]=new int[2][3]
动态语法2:
先声明:类型 数组名[][];
再定义(开辟空间) -> 数组名 = new 类型[大小][大小]
赋值(有默认值,比如 int 类型的就是 0)
使用方式 3: 动态初始化-列数不确
//创建 二维数组,一个有 3 个一维数组,但是每个一维数组还没有开数据空间
int[][] arr = new int[3][];
for(int i = 0; i < arr.length; i++) {//遍历 arr 每个一维数组
//给每个一维数组开空间 new
//如果没有给一维数组 new ,那么 arr[i]就是 null
arr[i] = new int[i + 1] 这里给一维数组开辟空间,arr[i]是指第i行的 所以new给i行开辟空间
静态初始化:
定义 类型 数组名![] = {{值1,值2..},{值1,值2..},{值1,值2..}}
使用即可【固定方式访问]
二维数组使用事项和注意方式
1 一维数组的声明方式有:
int[] x 或者 int x[]
2 二维数组的声明方式有:
int[][] y 或者 int[] y[] 或者 int y[][]
3 二维数组实际上是由多个一维数组组成的,它的各个一维数组的长度可以相同,也可以不相同。比如: map[][] 是
一个二维数组
int map [][] = {{1,2},{3,4,5}},由 map[0] 是一个含有两个元素的一维数组 ,map[1] 是一个含有三个元素的一维数组构成,我们也称为列数不等的二维数组
第6章 面向对象编程(基础部分)(oop)
类与对象
概念:
类就是自己自定义的一个数据类型,对象就是 类的实例 ->(自己理解:类就是一个自己定义的数据类型,对象就是数据类型的实例(实体,把抽象的类,给具体化出来(new),),Cat1就是对象引用 或者对象名)
举例:
1 new Cat() 创建一只猫(猫对象)
2 Cat cat1 = new Cat(); 把创建的猫赋给 cat1 (因为你创建猫的类型是cat类的 所以要Cat cat)
3 cat1只是个名字,new的才是对象的具体化
匿名写法:顾名思义就是没名字,new 类名().方法 匿名使用,这个对象也是在堆里面-但是只能用一次,使用后就被销毁了
对象在内存中的布局
首先 对象是一个引用类型,所以有地址,地址存在堆区 ,堆区里的属性String又是引用类型(地址) 所以存放的是地址在,堆区的引用类型(地址)存在方法区的常量池, 堆区的基本类型存放在堆里,
在new时会加载类的信息在方法区,new的时候会在堆开辟空间地址(属性new的时候是默认值 后来才赋值)
属性与成员变量(字段,属性,成员变了)
1 从概念或叫法上看: 成员变量 = 属性 = field(字段) (即 成员变量是用来表示属性的,授课中,统一叫 属性
2 属性是类的一个组成部分,一般是基本数据类型,也可是引用类型(对象,数组)。比如我们前面定义猫类 的 int age 就
是属性
属性的注意细节
1 属性的定义语法同变量,示例:访问修饰符 属性类型 属性名;
这里老师简单的介绍访问修饰符: 控制属性的访问范围
有四种访问修饰符 public, proctected, 默认, private ,后面我会详细介绍
2 属性的定义类型可以为任意类型,包含基本类型或引用类型
3 属性如果不赋值,有默认值,规则和数组一致。具体说: int 0,short 0, byte 0, long 0, float 0.0,double 0.0,char \u0000,boolean false,String nul
Cat1就是对象引用 或者对象名
注意:
Person p1 = new Person()
p1 是对象名(对象引用)
new Person() 创建的对象空间(数据) 才是真正的对象(new的时候才是真正的对象 实例化)p1只是给了个名字 存放new的对象
如何创建对象和访问对象属性
创建对象:
1 先声明再创建
Cat cat ; //声明对象 cat 此时是null(地址)的,new后把地址赋值给它
cat = new Cat(); //创建
2 直接创建
Cat cat = new Cat()
访问属性:
基本语法
对象名.属性名;
类和对象的内存分配机制(重要)
类加载过后,在堆里面生成class文件
在new时,会把类的信息 加载到方法区
java内存的结构
1 栈: 一般存放基本数据类型(局部变量),栈内存是Java的另一种内存,主要是用来执行程序用的,比如:基本类型的变量和对象的引用变量
2 堆: 存放对象(Cat cat , 数组等)
3 方法区:常量池(常量,比如字符串), 类加载信息(类信息只会加载一次)
成员方法(函数)
用法:访问修饰符 返回类型 方法名字(参数){要运行的代码快}
好处:
提高代码的复用性
可以将实现的细节封装起来,然后供其他用户来调用即可,
调用时才执行,开辟空间
方法的调用机制(内存分析)
注意点: 1.方法在栈开辟独立的空间
2当方法执行完毕 或执行到return语句推出,
3.返回的地方 的调用的地方,哪里调用返回哪里
方法成员的定义
访问修饰符 返回数据类型 方法名(形参列表..) {//方法体
语句;
return 返回值;
}
1 形参列表:表示成员方法输入 cal(int n) , getSum(int num1, int num2)
2 返回数据类型:表示成员方法输出, void 表示没有返回值
3 方法主体:表示为了实现某一功能代码块
4 return 语句不是必须的。(如果没return就是运行到最后才结束方法)
方法使用细节
访问修饰符 (作用是控制 方法使用的范围):
如果不写默认访问 (有四种: public, protected, 默认, private), 具体在后面说
返回数据类型:
1 一个方法最多有一个返回值 (思考,如何返回多个结果 返回数组就是返回多个)
2 返回类型可以为任意类型,包含基本类型或引用类型(数组,对象)
3 如果方法要求有返回数据类型,则方法体中最后的执行语句必须为 return 值; 而且要求返回值类型必须和 return 的
值类型一致或兼容 (兼容就是 返回的数据类型可以自动转换 例如 返回 int 给double)
4 如果方法是 void,则方法体中可以没有 return 语句,或者 只写 return ; 不能有有返回值
方法名:
遵循驼峰命名法,最好见名知义,表达出该功能的意思即可, 比如 得到两个数的和 getSum, 开发中按照规范,在实际工作中,我们的方法都是为了完成某个功能,所以方法名要有一定含义,方法名
首字母小写,如 addOrder() 不要 AddOrder()
动词在前,如 addOrder(),不要orderAdd()
参数列表:
定义是的参数叫形参,调用时叫实参,个数,顺序要一致
不能嵌套定义方法 定义
方法调用细节:
1.同一个类中的方法调用:直接调用即可。比如print(参数);案例演示:A类 sayOk 调用 print() ->就是不用new可以直接名字使用
2.跨类中的方法A类调用B类方法:需要通过对象名调用。比如对象名.方法名(参数);案例演示:B类 sayHello 调用 print()
3.特别说明一下:跨类的方法调用和方法的访问修饰符相关,先暂时这么提一下后面我们讲到访问修饰符时,还要再细说
方法的传承机制(很重要)
引用类型传递的是地址(传递也是值,但是值是地址),可以通过形参影响实参!
坑:
这块代码运行结果是 10,因为你B类的p和上面类的p指向同一个地址,这个b类的p只是赋值,这里把p赋值为null不影响上面,相当于两个同时指向一个
克隆对象
方法的递归(重要)
简单的说: 递归就是方法自己调用自己,每次调用时传入不同的变量,递归有助于编程者解决复杂问题,同时可以让代码变得简洁
1.各种算法中也会使用到递归,比如快排,归并排序,二分查找,分治算法等.
2.将用栈解决的问题-->递归代码比较简洁
递归的执行机制
方法递归的内存:
递归就是 先进后出,后进先出和栈一样,看后一个条件即可
递归重要规则
1 执行一个方法时,就创建一个新的受保护的独立空间(栈空间)
2 方法的局部变量是独立的,不会相互影响,比如n变量
3 如果方法中使用的是引用类型变量(比如数组),就会共享该引用类型的数据.
4 递归必须向退出递归的条件逼近,否则就是无限递归,出现StackOverflowError,死龟了:)
5 当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕。
斐波那契:
看整体 例如:求过的n1(2) = 1 n1(3) = 2 直接代入
猴子偷桃 逆推思维
思路:是从第十天开始计算 使用递归 到达10就返回值1
为啥是 (x+1)*2 因为你吃了一半 再吃一个就不是一半了,要补回去一半,所以+1 你也可以互推看看 数目是否对
(后面桃子 +1) *2 正常 因为你是吃了一半 和多一个 所以
迷宫:
1 findWay 方法就是专门来找出迷宫的路径
2 如果找到,就返回 true ,否则返回 false
3 map 就是二维数组,即表示迷宫
4 i,j 就是老鼠的位置,初始化的位置为(1,1)
5 因为我们是递归的找路,所以我先规定 map 数组的各个值的含义
0 表示可以走 1 表示障碍物 2 表示可以走 3 表示走过,但是走不通是死路
6 当 map[6][5] =2 就说明找到通路,就可以结束,否则就继续找.
上下左右走不通就会 回溯 赋值成3
方法的重载(形参的数据类型个数或顺序需要不一样,方法名字一样,返回类型和重载没关系(无要求))
java中允许同一个类中,多个同名方法的存在,但要求 形参列表不一致!
比如:System.out.println(); out是PrintStream类型
重载的好处:减轻了起名的麻烦 减轻了记名的麻烦
本类使用
使用细节:
注意:传参是如果 传的参数是int 无匹配,但是有一个方法重载doulie类型 也会匹配,如果有int形参优先匹配int
可变参数(方法重载的封装)(当数组使用)
java允许将 同一个类中 多个同名 同功能 但参数个数不同的方法,封装成一个方法。
可变参数使用方式:
当数组使用
基本语法:
这里就是 多个数据类型 ->根据传入的参数匹配
可变参数细节
本质就是数组,可以传数组
第四点是 传参的时候 可变参数和普通的参数可以一起放在传承列表里,但是保证可变参数在最后, (可以把可变参数看成一个参数)
一个形参列表只能出现一个可变参数
作用域
基本使用
{}这样是代码块(以后会讲)
注意事项
构造方法/构造器(初始化对象)
基本语法:
[修饰符] 方法名(形参列表){
方法体;
}
1 构造器的修饰符可以默认, 也可以是 public protected private
2 构造器没有返回值
3 方法名 和类名字必须一样
4 参数列表 和 成员方法一样的规则
5 构造器的调用, 由系统完成
构造器是初始化对象 不是创建对象,当你调用构造器时,对象已经创建了已经在堆里面存在了,空间分配好了
构造器的注意事项
构造器重载和方法 一样
这里有个注意点: 就是一旦自己定义了构造器,默认无参的构造器就会被覆盖,new时如果使用无参构造器就会出错,或者你在写一个无参的
对象内存分析(有构造器)
new 的时候构造器才开始执行,由系统执行
在内存里的对象 刚开始是默认初始化 -> 显示初始化 -> 构造器调用时初始化
this关键词(访问当前对象的 属性,方法,构造器)
引出问题
这里作用域问题,就近原则,最近的变量(局部变量)是在方法里面的,所以name在这个方法结束后,销毁
this(可以理解对象的本身,指向它自己)就是当前对象的属性,什么是当前对象 -> new 的时候创建的对象
this注意细节
1 this 关键字可以用来访问本类的属性、方法、构造器
2 this 用于区分当前类的属性和局部变量
3 访问成员方法的语法:this.方法名(参数列表);
4 访问构造器语法:this(参数列表); 注意只能在构造器中使用(即只能在构造器中访问另外一个构造器, 必须放在第一
条语句) 语法必须要这样写 因为this和类重叠的,this和填入相关参数
5 this 不能在类定义的外部使用,只能在类定义的方法中使用。
本章小结
return 返回null,也是返回地址
编程思维,例如:猜拳游戏,可以把出拳0 1 2,定义一个函数,比赛订一个函数,猜拳结果定一个函数,->就是把这些模块定义成函数调用,先分析拆开,一块一块 在把获取的出拳存到二维数组,和结果也存到
第七章 面向对象(中级)
类加载(类在什么时候被加载)
类会在以下几种情况下被加载:
(1)类被实例化:当你创建类的一个实例(通过 new 关键字)时,与该实例相关的类将被加载。
(2)访问类的静态成员:如果你访问一个类的静态字段或静态方法,该类将被加载。
(3)通过反射访问类:使用反射机制(Class.forName() 或 .class 字面量等)来访问一个类时,它会被加载。
(4)启动时加载的类:JVM在启动时会加载一些系统类,例如java.lang.Object。
(5)初始化一个类的子类:如果一个类有子类,当子类被初始化时,父类也会被加载。
(6)调用类的主方法:当你通过 java 命令运行一个类的 main 方法时,该类将被加载。
类销毁:
该类所有的实例都已经被回收,也就是java堆中不存在该类的任何实例
类信息是什么:
Class就是一个普通的类,就是用来描述一个类的信息的(比如类有几个字段,几个方法,名字叫什么等等 )
可以通过 3 种方法来获取Class的对象,也就是某个类的字节码
有个某个类的字节码以后,我们就知道知道这个类的许多信息了
Class一般是在运行时使用,你只要告诉我类名,我就可以知道这个类中有多少方法,有多少字段,怎么调用等等
类加载器过程
网上找到的资料:
每个类在加载的时候都会创建一个字节码对象,,例如:dog.java ->javac dog.java,生成 java.class文件,
首先是将类加载到方法区的class内容区,这里有两个类Person.class和PersonDemo.class,会被加载到class内容区。
当运行程序的时候,需要用到一个类,会先到方法区查找class信息,如果找到了就拿来用。如果没找到,就会像上面这样,将class类文件加载到方法区里面。(只会加载)
遇到new关键字的时候,将需要将创建对象的类加载 初始化初始化给对象
加载步骤:在.class加载到方法区时,先加载父类再加载子类;先加载静态内容,再加载非静态内容,到这里为止,整个类的加载就完成了
.class文件读入内存,让类加载完之后会生成一个Class类型对象,这个对象会包含类的数据结构,包含所有信息(比如类名,方法,变量等)
静态变量是地址
idea
在idea里 run一个文件时, 会先编译成 .class ->在运行) ,class文件(字节码)在out目录下
快捷键: 快捷键都是对应单词的
1 删除当前行, 默认是 ctrl + Y 自己配置 ctrl + d (delete)
2 复制当前行, 自己配置 ctrl + alt + 向下光标(duplicate)
3 补全代码 alt + /
4 添加注释和取消注释 ctrl + / 【第一次是添加注释,第二次是取消注释】
5 导入该行需要的类 先配置 auto import(General) , 然后使用 alt+enter 即可
6 快速格式化代码 ctrl + alt + L (搜索:Reformat Code)
7 快速运行程序 自己定义 alt + R () (RUn)
8 生成构造器等 alt + insert [提高开发效率]
9 查看一个类的层级关系 ctrl + H [学习继承后,非常有用]
10 将光标放在一个方法上,输入 ctrl + B , 可以定位到方法 [学继承后,非常有用]
11 自动的分配变量名 , 通过 在后面假 .var [老师最喜欢的] (就是对象后面.var)类.var
模板:
file ->settings -> editor-> Live templates ->
查看有哪些模板快捷键/可以自己增加模板 前期尽量不要使用
包
包的本质
实际上就是 创建不同的文件夹/目录来保存类文件,
例图:
com.xiaoming 点是一级目录点完后是二级目录 .
import 引入包
同一个类名,引入包 第一个引入包了,不用.包
补全就不用引入 直接. (包名.类名 对象名)
包的命名规则与规范
java常用的包
一个包下,包含很多的类,java 中常用的包有:
1 java.lang.* //lang 包是基本包,默认引入,不需要再引入.
2 java.util.* //util 包,系统提供的工具包, 工具类,使用 Scanner
3 java.net.* //网络包,网络开发
4 java.awt.* // 是做 java 的界面开发,
如何引入包
用 只引入一个类比较好,用到哪个类导入那个类
注意事项
注意事项和使用细节
1.package 的作用是声明当前类所在的包需要放在class的最上面,一个类中最多只有一句package
2.import指令 位置放在package的下面,在类定义前面,可以有多句且没有顺序要求。
访问修饰符(可以修饰的对象,属性,方法)
java 提供四种访问控制修饰符号,用于控制方法和属性(成员变量)的访问权限(范围): 访问就是 点 .
1 公开级别:用 public 修饰,对外公开
2 受保护级别:用 protected 修饰,对子类和同一个包中的类公开
3 默认级别:没有修饰符号,向同一个包的类公开.
4 私有级别:用 private 修饰,只有类本身可以访问,不对外公开.
方法修饰符的细节
只有默认和public才能修饰类
类只有默认和public才能
注意:一个源文件中最多只能有一个public类
面向对象的三大特征
封装
封装介绍:
封装(encapsulation)就是把 抽象出的 数据(属性)和对 数据的 操作(方法) 封装在一起,数据被保护在内部,程序的其它部分只有通过被授权的操作(方法),才能对数据进行操作。(可以理解为 把复杂的程序封装方法后变成 用户简单简单使用的方法,例如:电视机的开关 使用者只需要开和关,但是内部发生的事情很多)
也就是说,当一个类中的变量被private(私有),他就无法在主程序中直接被调用,那么咱们就需要其他的方法,进行赋值。
封装就是:不让别人随意修改属性,因为有些属性有些要求,例如年龄就是一般都是1-120,把年龄封装起来,然后写业务或安全逻辑,这就是封装
封装的理解和好处:
封装步骤 (把属性私有化似乎是这样)
set方法是给他修改设置属性值的,get方法是给返回属性值
其实可以理解为 就是把属性私有化,保证数据的安全合理,可以对数据验证或者 (自己理解:或者这个封装就是为了属性的私有)
好处:1.对象的属性不能随意修改,2.可以在封装里的方法加入业务逻辑
封装与构造器
构造器可以初始化属性 包括私有属性,这样封装就没用处了,但是把封装的set写到构造器中这样仍然可以验证数据,继续完成业务
继承
继承可以解决代码复用,让我们的编程更加靠近人类思维,当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过extends来声明继承父类即可。
好处:扩展性变高了,代码复用解决了
基本语法:
继承的基本语法class 子类 extends 父类{ }
1 子类就会自动拥有父类定义的属性和方法
2 父类又叫 超类,基类。
3 子类又叫派生类。
原理图:
开发时 也可以说 D是A的子类
继承的细节
1 子类继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问, 但是私有属性和方法不能在子类直接访
问,要通过父类提供公共的方法去访问
2 子类必须调用父类的构造器, 完成父类的初始化 ,(子类构造器 默认自带一个super 父类初始化)
3 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用 super 去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过(怎么理解。) (子类构造器 默认自带一个super 父类初始化,如果父类没有提供无参构造器,子类必须要指定父类构造器初始化 用super)
4 如果希望指定去调用父类的某个构造器,则显式的调用一下 : super(参数列表)
5 super 在使用时,必须放在构造器里面的第一行(super 只能在构造器中使用)
6 super() 和 this() 都只能放在构造器里面的第一行(这两个),因此这两个方法不能共存在一个构造器 (构造器中使用)
7 java 所有类都是 Object 类的子类, Object 是所有类的基类.
8 父类构造器的调用不限于直接父类!将一直往上追溯直到 Object 类(顶级父类) (构造器执行也是,其实很容易理解,super方法必须在第一行)
9 子类最多只能继承一个父类(指直接继承),即 java 中是单继承机制。(只能有一个父类,a类不能继承c d两个类 以上)
思考:如何让 A 类继承 B 类和 C 类? 【A 继承 B, B 继承 C】
10 不能滥用继承,子类和父类之间必须满足 is-a (就是 子类 是 父类 的什么,例如 猫是动物 )的逻辑关系
每个子类构造器有一个super,注意隐藏super和this
继承的本质分析
对象的内存:
首先加载son,因为还有父类所以查找父类 加载父类
查找属性或方法时 就近原则
查找顺序:
1 首先看子类是否有该属性
2 如果子类有这个属性,并且可以访问,则返回信息
3 如果子类没有这个属性,就看父类有没有这个属性(如果父类有该属性,并且可以访问,就返回信息..)
3 如果父类没有就按照(3)的规则,继续找上级父类,直到0biect.
super(用于指定父类)
基本介绍:
super代表父类的引用,用于访问父类的属性、方法、构造器
基本语法:
1 访问父类的属性,但不能访问父类的private属性 super.属性名:
2 访问父类的方法,不能访问父类的private方法 super.方法名(参数列表);
3 访问父类的构造器(这点前面用过):super(参数列表);只能放在构造器的第一句,只能出现一句!
好处与便利:
1 调用父类的构造器的好处“明确,父类属性由父类初始化,子类的属性由子类初始化)
2 当子类中有和父类中的成员(属性和方法)重名时,为了访问父类的成员,必须通过super。如果没有重名使用super、this、直接访问是一样的效果
3 super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用super去访问爷爷类的成员;如果多个基类中都有同名的成员,使用super访问遵循就近原则。A->B->C
this的查找规则是:先找本类没有,再找父类,(cal()和this.cal()一样)
super:直接查找父类 如果上一个父类没 就上上一个
this和super区别:
方法重写
基本介绍:
简单的说:方法覆盖(重写)就是子类有一个方法,和父类的某个方法的名称、返回类型、参数一样,那么我们就说子类的这个方法覆盖了父类 (多层的父类也可以)的那个方法
就近原则
方法重写的注意事项
多态(难度最大)
多(多种)态(状态)介绍:
方法或对象具有多种形态。是面向对象的第三大特征,多态是建立在封装和继承基础之上的。
1.方法的多态: 重写或重载体现多态,就是我们传入不同的参数调用不同的方法
2.对象的多态(多态的核心):
感觉是父类的引用指向了子类的对象)
(1)一个对象的编译类型和运行类型可以不一致
(2)编译类型在定义对象时,就确定了,不能改变
(3)运行类型是可以变化的.编译类型看定义时 =号 的左边,运行类型看=号的 右边
例如:animal 编译类型是Animal,可以指向(接收),Aaimal子类的对象
可以理解为,就是用父类的引用,把子类的类赋值给父类,然后每次传入参数 可以随意变化,因为运行类型是子类的 右边,
Animal animal = new dog(); 参数是父类Animal 所以传入 子类 可以 用 父类的引用调用
其实多态就是 一个父类的 引用指向子类的地址, 子类开辟空间就把地址传过去
多态的注意事项和细节讨论
多态的向上转型:
不能调用子类中的特有成员,这就是向上转 父类引用指向子类
为什么不能调用? 因为在编译阶段,能调用那些成员 是由 编译类型决定的,运行类型只是javac后的
最终运行效果看子类(运行类型)的具体实现,即调用方法时,按照从子类(运行类型)开始查找方法然后调用,规则我前面我们讲的方法调用规则一致。
多态的向下转型:
此时的运行类型和编译类型 都是子类
多态的属性和比较对象函数
属性没有重写之说, 属性的值看 编译类型,在使用时看编译类型
判断 xx 是 xx 的 类型或着子类 , 看右边运行类型,有两个一个是类型 一个是子类
xx看的是运行类型 应该是xx的运行类型是xx的类型或子类
==用来比较两个对象的地址是否相等。,主要用来上下转换时的类型
Java的动态绑定(非常重要)多态的
java的动态绑定机制: 和多态密切相关的
(1)当调用对象方法的时候,该方法会和该对象的运行类型绑定 ,如果运行类型没这个方法就会往上找
(2)当调用对象的属性时,没有动态绑定机制,哪里声明就在哪里使用
多态的应用
(1)多态数组:
多态数组 数组定义为父类类型,里面保存子类类型,因为父类的引用可以指向子类对象
(2)多态参数:
方法定义的形参类型为父类类型,实参类型允许为子类类型
Object类
==方法
equals方法
只能判断引用类型
equals的 this 是 xxx.equals(xxx) xxx.就是xxx.的
其实 .equals 可以理解为 xxx对象的调用方法, xxx对象继承了Object类,调用Object的equals方法,this是找本类的对象,
this就是当前对象 ,this就是谁调用就是谁是对象
hashCode
Java是跑在虚拟机上的,所以是无法拿到这个对象的地址
toString
finalize (当对象被回收时,系统会自动调用该对象的这个方法)
程序员就可以在 finalize中,写自己的业务逻辑代码(比如释放资源:数据库连接,或者打开文件。)
断点调试
第八章 面向对象(高级)
类变量(static)(用处:统计某些数)(可以修饰的对象,属性,方法)
static 不能修饰构造器 因为构造器是new时触发的,static是类加载的
存放在 堆区 静态变量 类变量是随着类加载而创建的
类加载是java JVM虚拟机在运行时进行的操作
对应类加载了 就会生成一个class实例 class里面就包含了static变量
共识:不管static 变量在哪里 (1)static 变量是同一个类所有对象共享(2)static类变量,在类加载的时候就生成了.
类变量:类变量也叫静态变量/静态属性,是该类的所有对象共享的变量,任何一个该类的对象去访问它时,取到的都是相同的值,同样任何一个该类的对象去修改它时,修改的也是同一个变量。这个从前面的图也可看出来。
父类拥有类变量 子类继承后 子类的 类名.属性 也可以调用,因为子类加载类时,父类也会加载,所以子类可以用
如何定义类变量:
定义语法:
(1)访问修饰符 static 数据类型 变量名;
(2)(推荐)static 访问修饰符 数据类型 变量名;
访问类变量:
(1)类名.类变量名
(2)对象名,类变量名
静态变量的访问修饰符的访问权限和范围 和 普通属性是一样的。
推荐使用:类名,类变量名:
区别:
数据存储位置不同
成员变量存储在堆内存的对象中,所以也叫对象的特有数据
静态变量存储在方法区(共享数据区)的静态区,所以也叫对象的共享数据
类变量注意事项和访问细节
类方法(用处:不想实例化,对象)
类方法的经典使用:
类方法的注意事项
this的参数
main方法语法
java命令时所传递的参数 的 java 类名 sss lll
特别注意:
1)在main()方法中,我们可以直接调用main方法所在类的静态方法或静态属性。
2)但是,不能直接访问该类中的非静态成员,必须创建该类的-通过这个对象去访问类中的非静态成员,
和静态方法一样其实
idea main传参
代码块
基本介绍:
代码块好处:
1)相当于另外一种形式的构造器(对构造器的补充机制),可以做初始化的操作
2)如果多个构造器中都有重复的语句,可以抽取到初始化块中,提高代码的重用性
因为多个构造器只能运行一个,所以可以使用代码块代码快初始化先
注意事项
调用顺序:
隐含 super后 **调用本类的普通代码块和普通的成员 ** 如果在构造器里面写,按顺序执行从上到下,首先super
知道有隐含的就可以
super 和 this 永远在第一句话 而且只能存在一个
设计模式
什么是设计模式
1.静态方法和属性的经典使用
2.设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格,以及解决问题的思考方式 。设计模式就像是经典的棋谱,不同的棋局,我们用不同的棋谱,免去我们自己再思考和摸索 ,不同的棋局,不同的套路
遇到类似的问题,就可以使用这种模式 相应
单例模式
单例(单个的实例)
1.所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个 取得其对象实例的方法
2.单例模式有两种方式:1)饿汉式 2)懒汉式
比如一个类的资源很大
饿汉式:
原理:只使用一个对象,没使用这个对象,但是还是自己创建了
饿汉式可能创建了没有使用,可能会浪费资源,因为饿汉式的对象都是资源重的
懒汉式:
懒汉式相当于 多了一个方法,这个方法调用时如果对象为null创建,如果不为空就就返回已经创建好的对象(上图右边)
final关键字
final使用细节
第七点 :final和static搭配使用,这个类不会加载,(面试时可说)有时候不需要加载用此方法
final 当作形参可以,赋值一次 值不能改变
抽象类(abstract)
当父类的一些方法不能确定时,可以用abstract关键字来修饰该方法,这个方法就是抽象方法,用abstract 来修饰该类就是抽象类。抽象方法没有方法体,和C语言一样声明
(不确定有什么作用,写了也没什么意义,所以可以声明抽象方法,抽象方法没有实现所以没有方法体,一般来说抽象类会被继承,由子类实现 重写)
抽象类的介绍
语法:abstract class na class na是创建一个类所以 abstract是访问修饰符 class 是创建 访问修饰符在前面
抽象类的细节和注意事项
1)抽象类不能被实例化
2)抽象类不一定要包含abstract方法。也就是说,抽象类可以没有abstract方法
3)一旦类包含了abstract方法,则这个类必须声明为abstract
4)abstract 只能修饰类和方法,不能修饰属性和其它的。
5)抽象类可以有任意成员【因为抽象类还是类】,比如:非抽象方法、构造器、静态属性等等
6)抽象方法不能有方法体, abstract void ooo();
7)如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,除非它自己也声明为abstract类。
8)抽象方法不能使用private、final 积static来修饰,因为这些关键字都是和重写相违背的
private是因为要子类 static是类加载和重写无关 final是因为不能被重写
这里也是动态绑定机制 因为是继承,关于继承都是动态绑定机制,看运行类型
抽象类最佳实践-模板设计模式
父类更好管理
接口
接口其实 就是实现接口的抽象方法
基本介绍:
最重要是可以管理,例如:写一个方法参数是接口,把对应接口传入会自动判断
接口的注意事项
接口也叫继承
接口与继承
因为继承是 单继承的只能有一个父类,实现接口就是 对 单继承的补充
当子类继承了父类,就自动拥有了父类的功能,因为是单继承,如果想给子类扩展功能,可以通过接口interface
接口和继承的关系
接口的多态
内部类
基本介绍:
内部类的分类:
成员就是属性或方法
局部内部类(本质上还是一个类)
局部内部类就是一个 局部变量 如果是外部类 new一下会在堆空间开辟一个地址
外部类使用局部内部类 要在局部作用域创建对象,在调用它的方法即可 必须在作用域
记住一句话,局部内部类 它定义的位置
作用域在什么地方
匿名内部类(很重要) (匿名内部类的名字 有$)
只使用一次,没有引用后会自动销毁就可以使用匿名内部类
new 类/接口(){}; 后面打了大括号就是匿名内部类 类名是$
(1)基于接口的
例子:
接口是不能直接 new的,所以 直接用 大括号 把接口的方法写清楚,写完后加个new,底层就会知道你这个是匿名内部类。
(2)基于类的(也可以基于抽象类的匿名类,但是抽象方法要实现)
注意:匿名内部类可以理解为,new时加个大括号,底层就知道你的是匿名内部类了,底层的运作是,一个匿名的引用 实现或者继承
然后把 这些地址给传到引用的类
匿名内部类的注意事项
上面两个使用方式
匿名内部类 最佳使用方式: 当作实参直接传递
例如: void dd(In in) 可以 直接 dd(new In{ 里面写实现方法}); 就相当于匿名类的引用赋值给了
这样会方便很多 用完就销毁
成员内部类
使用的话 在外部类定一个返回内部类里面的属性或者方法
右边的代码是 外部其他类访问成员内部类 第一个方式可以理解为 外部类的属性然后 点. ,第二种方式 和第一种一样,就是直接new了后 在.在new一下 第一个的结合
第三个方法 是用一个方法返回 内部类 即可
静态内部类
外部其他类 访问 静态内部类 就是外部类.内部类就可以了 因为是静态 静态可以调用类名
因为都是在类里面
第十章 枚举和注解
枚举(enum开发一个枚举类,默认会继承enum)
枚举介绍:
1)枚举对应英文(enumeration,简写 enum)
2)枚举是一组常量的集合。
3)可以这里理解:枚举属于一种特殊的类,里面只包含一组有限的特定的对象
枚举的两种实现:
1)自定义类实现权举
枚举就是 一组常量 不可被修改的,所以要把构造器给私有,只给一个get方法,给一个暴露对象方便调用
小结:
2)使用enum 关键字实现枚举
枚举的注意事项
javac dog.java -> dog.class javap dog.class -> dog.java
本质还是个类
enum常用方法 (因为使用了enum就会隐式的继承enum)
利用数组方法
注解(Annotation)
注解的理解
Override
@Target修饰注解的注解 叫元注解
Deprecated
修饰某个元素, 表示该元素已经过时了,既不推荐使用,但是还是可以使用, 当被注释的变量,使用时会有下划线
用处的过渡 例如 jdk8 升级到 jdk11 jdk11里面有一个类过度了 就可以用这个注解
suppersWarnings
通常放在方法和类
关于 SuppressWarnings 作用范围是和你放置的位置相关
比如 @SuppressWarnings 放置在 main 方法,那么抑制警告的范围就是 main
该注解类有数组 String[] values() 设置一个数组比如 {"rawtypes", "unchecked"} 可以传入多个参数
JDK元注解
Retention
Target
Documented
Inherited
第十一章 异常
异常(exception)
就是不是很致命的问题,就会抛出异常 比如:10 / 0
ctrl + alt + t 把包起来的代码
异常介绍
● 基本概念Java语言中,将程序执行中发生的不正常情况称为“异常”(例如:10 / 0)。((开发过程中的语法错误和逻辑错误不是异常)
● 执行过程中所发生的异常事件可分为两类:
- Error(错误):Java虚拟机无法解决的严重问题。如:JVM系统内部错误资源耗尽等严重情况。比如:StackOverflowError(栈溢出)和OOM(out ofmemory),Error 是严重错误,程序会崩溃。
2)Exception: 其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如空指针访问,试图读取不存在的文件,网络连接中断等等,Exception 分为两大类:运行时异常 (程序运行时,发生的异常)和编译时异常(编程时,编译器检查出的异常)。 编译就是还在写代码的时候 ,运行就是运行代码时 (编译异常 必须要处理)
异常的体系图
蓝色的实线是继承,虚线是实现关系
小结:
常见的运行时异常
- NullPointerException空指针异常,当应用程序试图在需要对象的地方使用 null 时,抛出该异常(就是对象还为null时,使用就会抛出异常)
- ArithmeticException数学运算异常当出现异常的运算条件时,抛出此异常。例如,一个整数“除以零”时,抛出此类的一个实例
- ArrayIndexOutOfBoundsException数组下标越界异常,用非法索引访问数组时抛出的异常。如果索引为负或大于等于数组大小,则,该索引为非法索引
- ClassCastException类型转换异常,将生成一个 ClassCastException,当试图将对象强制转换为不是实例的子类时,抛出该异常。
5)NumberFormatException数字格式不正确异常,当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适,当格式时,抛出该异常 =>使用异常我们可以确保输入是满足条件数字.
编译异常
异常处理
基本介绍:异常处理就是当异常发生时,对异常处理的方式。
异常处理的方式:
- try-catch-finally程序员在代码中捕获发生的异常,自行处理
流程图:
finally 要优先输出
处理异常说明:
1)Java提供try和catch块来处理异常。try块用于包含可能出错的代码。catch块用
于处理try块中发生的异常。可以根据需要在程序中有多个数量的try...catch块。
2)基本语法
try {
//可疑代码
//将异常生成对应的异常对象,传递给catch块
}catch(异常){
//对异常的处理
}
注意细节:
finally 要优先输出
- throws
将发生的异常抛出,交给调用者(方法)来处理,最顶级的处理者就是JVM
介绍:
1)如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何处理这种异常,则此方法应显示地声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理。
2)在方法声明中用throws语句可以声明抛出异常的列表,throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类。
throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类throws (exception)
关键字后也可以是异常列表,即可以抛出多个异常
注意与事项:
运行异常,不要求程序员处理,因为有默认处理机制(或者你抛出是运行有异常,要是抛出是编译异常就报错),但是编译异常一定要程序员处理,否则还没开始就报错了 运行异常的默认处理机制就是一直仍到JVM暴力处理 (默认抛出运行异常)
自定义异常
自定义异常步骤:
1)定义类:自定义异常类名(程序员自己写)继承Exception或RuntimeException,(然后判断条件抛出 throw)
2)如果继承Exception,属于编译异常
3)如果继承RuntimeException,属于运行异常(一般来说,继承RuntimeException)
throw 和 throws区别
finally 要优先输出
也可以throw抛出java已经定义好了 的异常,用来抛出去 然后t - c - f 判断
第十二章 常用类(面试会问到)
包装类
八大wrapper(包装类)类
为什么会有包装类:
Java是一个面相对象的编程语言,基本类型并不具有对象的性质,为了让基本类型也具有对象的特征,就出现了包装类型(如我们在使用集合类型Collection时就一定要使用包装类型而非基本类型),它相当于将基本类型“包装起来”,使得它具有了对象的性质,并且为其添加了属性和方法,丰富了基本类型的操作。
包装类的介绍
面向对象最重要的是继承体系,只要把继承体系搞懂了就不会乱
装箱和拆箱(装箱: 基本数据类型 -> 包装类 拆箱: 包装类 -> 基本数据类型 )
底层调用,debug即可, 把100这样直接传入封箱也可以 例如:Double d = 100d 底层自动封箱 = Double.valuof(100)
自动装箱 就是 JDK帮我包裹了一下 其实还是前面手动一样 底层可查看
先创建obj1 然后判断了true 从ture后是一个整体 会精度提升
包装类(Integer) --> String
String --> 包装类(Integer)
Integer(创建机制)
题目:
包装类的方法
Integer类和Character类的常用方法:
String(重点)
String结构解析
final char[] aa 其实是 地址不可修改,但是char数组里面的值是可以的 , 可以修改里面的字符 但是地址不能修改,也就是不能指向别人 更换地址(及创建新对象) (估计是创建常量池的字符串)相当于每个新的字符串常量就会在常量池 创建新的一个地址
final是常量 指的是数组常量 ,如果是普通的话是字符常量
String创建
.intern()方法是返回字符串常量的地址
String对象特征
面试题:
题目1:
题目2:
String的常用方法
String的常用方法:
实例1:
实例2:
format和 printf使用方法一致,前面写格式 format("%d",sum)
Stringbuffer(对String类的增强,使用在多线程 )
基本介绍:
可以看成字符数组 使用
区别:
Stringffer 构造器
Stringbuffer转换:
Stringbuffer常用方法
替换(9, 11) 从第九个位置开始,11不包含
Stringbuildre(使用在单线程)
基本介绍: 和Stringbuffer一样,但是这个在单线程使用
Stringbuilfre和Stringbuffer和String 区别
选择
:
Math类(数学相关的,查手册即可)
基本介绍
Arrays类
定制排序就是 把系统的接口重写 然后通过动态绑定机制传入
System类
BigInteger类 和 BigDecimal类(大数处理方案比double和long还大)
应用场景:
1)BigInteger适合保存比较大的整型
2)BigDecimal适合保存精度更高的浮点型(小数)
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。