选择排序&二分查找&异常
能够理解选择排序的执行原理
选择排序:使用数组中的元素依次和其他的元素比较,把小的值往前放
能够理解二分查找的执行原理
使用公式:mid = (min+max)/2;
使用被查找的元素和中间索引指向的元素比较,循环执行的条件 min<=max
1.被查找的元素>中间指针执向的元素 min = mid+1;
2.被查找的元素<中间指针执向的元素 max = mid-1;
3.被查找的元素==中间指针执向的元素 找到了,返回mid
能够辨别程序中异常和错误的区别
错误:严重的问题,必须修改代码才能解决
异常:可以解决的问题,使用try...catch解决异常之后,程序可以继续执行
说出异常的分类
编译期异常==>Exception:写代码的时候会报的异常
运行期(时)异常==>RuntimeException:运行代码的时候报的异常
列举出常见的三个运行期异常
ClassCastException:类型转换异常(向下转型)
NullPointerException:空指针异常
IndexOutOfBoundsException:索引越界异常(集合会抛出)
ArrayIndexOutOfBoundsException:数组索引越界异常
StringIndexOutOfBoundsException:字符串索引越界异常
能够使用try...catch关键字处理异常(重点) ctrl+alt+t
try{
可能产生异常的代码
throw new xxxException("异常的信息");
...
throw new yyyException("异常的信息");
}catch(xxxException e){
异常的处理逻辑
}
...
catch(yyyException e){
异常的处理逻辑
}
能够使用throws关键字处理异常(重点) alt+回车
修饰符 返回值类型 方法名(参数) throws xxxException,...,yyyException{
throw new xxxException("异常的信息");
...
throw new yyyException("异常的信息");
}
能够自定义并使用异常类
1.自定义异常的类名,一般都是以Exception结尾,说明这个类是一个异常相关的类(见名知意)
2.自定义异常
a.必须继承Exception:自定义的异常就是一个编译期异常
使用:如果在方法内部抛出了编译期异常,那么我们就必须处理这个异常
1.使用throws声明抛出异常,最终抛出给方法的调用者处理
2.使用try...catch自己捕获处理异常
b.必须继承RuntimeException:z自定义的异常就是一个运行期异常
使用:如果在方法内部抛出了运行期异常,我们无需处理,默认交给JVM处理(中断处理)
第一章 选择排序(重点)
1.原理
2.代码实现
package com.itheima.demo01sort;
import java.util.Arrays;
/*
选择排序:使用中的元素依次和其他的元素进行比较,每次选出最小的值,把小的值往前放
*/
public class Demo01SelectSort {
public static void main(String[] args) {
//定义一个数组
int[] arr = {5,1,8,3};
System.out.println("排序前数组中的元素:"+ Arrays.toString(arr));
/*
选择排序
1.定义一个循环嵌套
外层循环:控制比较的次数 arr.length-1
内层循环:控制每次比较几对元素 int j = 1+i
2.在循环中依次比较arr[i]和arr[j]的值,每次选出最小的
在if语句中使用第三方变量交互两个元素的位置
*/
//1.定义一个循环嵌套
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 1+i; j < arr.length; j++) {
//2.在循环中依次比较arr[i]和arr[j]的值,每次选出最小的
if(arr[i]>arr[j]){
//在if语句中使用第三方变量交互两个元素的位置
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
System.out.println("每次排序的结果:"+ Arrays.toString(arr));
}
System.out.println("排序后数组中的元素:"+ Arrays.toString(arr));
}
}
排序前数组中的元素:[5, 1, 8, 3]
每次排序的结果:[1, 5, 8, 3]
每次排序的结果:[1, 3, 8, 5]
每次排序的结果:[1, 3, 5, 8]
排序后数组中的元素:[1, 3, 5, 8]
第二章 二分(折半)查找(重点)
1.原理
2.代码实现
package com.itheima.demo02search;
/*
二分(折半)查找
前提:
数组|集合中的元素必须是有序的(升序)
*/
public class Demo01BinarySearch {
public static void main(String[] args) {
int[] arr = {-10,0,11,30,66,88};
int i1 = binarySearch(arr, 66);
System.out.println("i1:"+i1);//i1:4
int i2 = binarySearch(arr, 100);
System.out.println("i2:"+i2);//i2:-1
int i3 = binarySearch(arr, -10);
System.out.println("i3:"+i3);//i3:0
}
/*
定义一个实现二分查找法的一个方法
1.方法的参数传递要查找的数组和被查找的数组
2.定义3个指针(min,mid,max)
3.遍历数组,使用被查找的数和中间指针指向的元素比较,循环执行的条件(min<=max)
被查找的元素>中间指针指向的元素 min = mid+1;
被查找的元素<中间指针指向的元素 max = mid-1;
被查找的元素==中间指针指向的元素 找到了,返回mid
4.循环结束了,还没有找到,返回-1
*/
//1.方法的参数传递要查找的数组和被查找的数组
public static int binarySearch(int[] arr,int number){
//2.定义3个指针(min,mid,max)
int min = 0;//指向最小的元素
int max = arr.length-1;//指向最大的元素
int mid = 0;
//3.遍历数组,使用被查找的数和中间指针指向的元素比较,循环执行的条件(min<=max)
while (min<=max){
//使用折半公式,计算mid的
mid = (min+max)/2;
if(number>arr[mid]){
//被查找的元素>中间指针指向的元素 min = mid+1;
min = mid+1;
}else if(number<arr[mid]){
//被查找的元素<中间指针指向的元素 max = mid-1;
max = mid-1;
}else{
//被查找的元素==中间指针指向的元素 找到了,返回mid
return mid;
}
}
//4.循环结束了,还没有找到,返回-1
return -1;
}
}
第三章 异常
1.异常的概念
异常 :指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止。
在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出了一个异常对
象。Java处理异常的方式是中断处理(停止java虚拟机JVM)。
2.异常的体系(重点)
package com.itheima.demo03Exception;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
异常和错误的区别(了解)
java.lang.Throwable:是异常和错误的父类
1.java.lang.Exception extends Throwable:异常(编译期异常),小问题,可以解决的,解决了异常之后,程序可以继续执行
java.lang.RuntimeException extends Exception:运行期异常,程序运行期间出现的异常
2.java.lang.Error extends Throwable:错误,严重的问题,不能解决
*/
public class Demo01Exception {
public static void main(String[] args) {
//编译期异常:写代码的时候(编译期,把.java文件编译生成.class文件),报的异常
/*try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = sdf.parse("2021-1129");
System.out.println(date);
} catch (ParseException e) {
e.printStackTrace();
}*/
//运行期异常,程序运行期间出现的异常
/*try {
int[] arr = {10,20,30};
System.out.println(arr[3]);
} catch (Exception e) {
e.printStackTrace();
}*/
/*
错误,严重的问题,不能解决
OutOfMemoryError: Java heap space 内存溢出的错误
创建的数组太大了,超出了内存使用范围,(内存中装不下了),就会报内存溢出的错误
必须的修改源码码,不让错误出现
*/
//int[] arr = new int[1024*1000*1000];
int[] arr = new int[1024*1000];
System.out.println("后续代码");
System.out.println("后续代码");
System.out.println("后续代码");
System.out.println("后续代码");
System.out.println("后续代码");
System.out.println("后续代码");
}
}
3.异常的产生过程解析(面试)
package com.itheima.demo03Exception;
/*
异常的产生过程解析
分析异常是如何产生的,产生异常之后,JVM是如何处理异常的
*/
public class Demo02Exception {
public static void main(String[] args) {
int[] arr = {10,20,30};
int ele = getElement(arr, 3);
System.out.println(ele);
}
/*
定义一个方法,获取数组指定索引处的元素返回
*/
public static int getElement(int[] arr,int index){
int e = arr[index];
return e;
}
}
4.throw关键字(重点)
throw:抛
作用:可以在方法中抛出指定的异常对象
package com.itheima.demo03Exception;
/*
throw关键字(重点)
作用:可以在方法中抛出指定的异常对象
格式:
修饰符 返回值类型 方法名(参数列表){
throw new Exception("异常信息");
throw new RuntimeException("异常信息");
throw new xxxxException("异常信息");
}
注意:
1.throw关键字必须写在方法中使用
2.throw关键字后边创建的异常对象,必须使用Exception或者RuntimeException的子类对象,不能使用(Person,Student...)
3.在方法中使用throw关键字抛出了编译异常,我们就必须处理这个编译异常
在方法中使用throw关键字抛出了运行期异常,我们可以不用处理这个异常,最终交给JVM处理(中断)
*/
public class Demo03throw {
public static void main(String[] args) {
//int[] arr = {10,20,30};
int[] arr = null;
int ele = getElement(arr, 2);
System.out.println(ele);
}
/*
定义一个方法,获取数组指定索引处的元素返回
在工作中:都会对方法传递进来的参数进行一些合法性的校验
参数合法,程序正常执行
参数不合法,以抛出异常的方法,告之方法调用者,传递的参数有问题
*/
public static int getElement(int[] arr,int index){
/*
对方法的参数数组arr进行合法性校验,判断arr是否为null
是null,使用throw关键字抛出空指针异常,告之方法的调用者"您传递的数组arr的值是null"
*/
if(arr==null){
throw new NullPointerException("您传递的数组arr的值是null");
}
/*
对方法的参数数组索引index进行合法性校验,判断索引是否在数组索引的范围内
不在索引范围内,使用throw关键字,抛出数组的索引越界异常,告之方法的调用者"您传递的数组的索引"+index+"不存在"
*/
if(index<0 || index>arr.length-1){
throw new ArrayIndexOutOfBoundsException("您传递的数组的索引"+index+"不存在");
}
int e = arr[index];
return e;
}
}
5.throws关键字(重点)
throws:抛出
异常处理的第一种方式:把产生的异常对象抛出给方法的调用者去处理
package com.itheima.demo03Exception;
/*
throws关键字(重点)
异常处理的第一种方式:把产生的异常对象抛出给方法的调用者去处理,建议练习的时候使用
作用:
方法的内部抛出了编译期异常对象,我们就必须的处理这个异常对象
可以使用throws关键字来处理异常对象,把这个异常对象抛出给方法的调用者处理
最终抛出给JVM处理,JVM会以红色的字体把异常对象相关信息打印的控制台,中断当前正在执行的程序
弊端:
产生异常的代码后边,还有其他的代码想执行,执行不到了,程序已经终止了
格式:
修饰符 返回值类型 方法名(参数列表) throws xxxException,...,yyyException{
throw new xxxException("异常的信息");
...
throw new yyyException("异常的信息");
}
注意:
1.throws关键字必须写在方法声明处
2.一般在方法内部抛出了什么异常对象,就使用throws关键字在方法上声明抛出什么异常对象
a.在方法内部抛出了多个异常对象,就需要使用throws关键字在方法上声明多个异常对象
b.在方法内部抛出的多个异常对象,如果有子父类关系,在方法上声明父类异常即可
3.调用一个使用throws关键字声明异常的方法,那么我们就必须处理这个异常对象
a.可以使用throws关键字继续声明抛出这个异常对象,最终会抛出给JVM处理
b.可以使用try...catch自己手动的处理异常
*/
public class Demo04throws {
/*
public static void main(String[] args) throws Exception
main方法接收到了getElement方法抛出的异常对象,把对象再继续抛出给JVM来处理==>中断处理
*/
public static void main(String[] args) throws Exception{
int[] arr = {10,20,30};
//int[] arr = null;
int ele = getElement(arr, 3);
System.out.println(ele);
System.out.println("后续100行代码...");
}
/*
定义一个方法,获取数组指定索引处的元素返回
在工作中:都会对方法传递进来的参数进行一些合法性的校验
参数合法,程序正常执行
参数不合法,以抛出异常的方法,告之方法调用者,传递的参数有问题
public static int getElement(int[] arr,int index)throws Exception
使用throws关键字:把创建的异常对象声明抛出给方法的调用者main方法处理
*/
public static int getElement(int[] arr,int index)throws Exception{
if(arr==null){
throw new Exception("您传递的数组arr的值是null");
}
if(index<0 || index>arr.length-1){
throw new Exception("您传递的数组的索引"+index+"不存在");
}
int e = arr[index];
return e;
}
}
6.throws抛出子父类异常的处理(重点)
在方法内部抛出的多个异常对象,如果有子父类关系,在方法上声明父类异常即可
package com.itheima.demo03Exception;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
在方法内部抛出的多个异常对象,如果有子父类关系,在方法上声明父类异常即可
public class FileNotFoundException extends IOException extends Exception
FileNotFoundException:文件找不到异常
IOException:读写异常
public static void main(String[] args)throws FileNotFoundException,IOException
FileNotFoundException和IOException是子父类异常,抛出父类异常即可
简化为:
public static void main(String[] args)throws IOException
public static void main(String[] args)throws Exception
*/
public class Demo05throws {
public static void main(String[] args)throws Exception {
//readFile("d:\\abc.java");
//readFile(null);
readFile("c:\\a.txt");
System.out.println("后续代码!");
}
/*
定义一个方法,方法的参数传递一个文件的路径: d:\\abc.java
在方法中根据文件的路径读取文件
*/
public static void readFile(String path)throws FileNotFoundException,IOException{
//判断路径path是否为null,是null抛出IOException
if(path==null){
throw new IOException("您传递的路径是null");
}
//判断路径path是否为d:\\abc.java,不是抛出FileNotFoundException
if(!"d:\\abc.java".equals(path)){
throw new FileNotFoundException("您传递的路径不是d:\\abc.java");
}
//根据路径读取文件
System.out.println("读取到了d:\\abc.java文件,文件中的内容是abc!");
}
}
7.try…catch关键字(重点)
package com.itheima.demo03Exception;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
try...catch关键字(重点):异常处理的第二种方式,建议在工作中使用
作用:
方法内部抛出了指定的编译期异常对象,我们就需要处理这个异常对象
调用的方法上声明抛出了异常对象,我们需要处理这个异常对象
可以使用try...catch关键字捕获处理异常,自己定义异常的处理方式
好处:
处理了异常对象之后,后续如果有代码,可以继续执行
格式:
try{
可能产生异常的代码(没有异常的代码)
}catch(定义一个异常相关的变量){ 变量的作用就是用来接收产生的异常对象
异常的处理逻辑(想怎么写就怎么写)
}
...
catch(定义一个异常相关的变量){
异常的处理逻辑(想怎么写就怎么写)
}
注意:
1.try中可能产生什么异常对象,catch中就要定义什么异常变量来接收这个异常对象
2.如果try中产生了异常对象,就会执行catch中异常的处理逻辑,执行完catch中的代码,继续执行try...catch后边的代码
3.如果try中没有产生异常对象,就不会执行catch中异常的处理逻辑,正常执行完try中的代码,继续执行try...catch后边的代码
4.如果try中产生了多个异常对象,就需要定义多个catch来捕获处理这些异常对象
-------------------------------------------
选中要添加try...catch的代码:按快捷键 ctrl+alt+t==>选择try...catch
*/
public class Demo06TryCatch {
public static void main(String[] args) {
try {
//可能会产生异常的代码
readFile("d:\\abc.java");
//readFile(null);
//readFile("c:\\a.txt");
}catch (FileNotFoundException e){//FileNotFoundException e = new FileNotFoundException("您传递的路径不是d:\\abc.java");
//异常的处理逻辑
System.out.println("哈哈");
}catch (IOException e) {//IOException e = new IOException("您传递的路径是null");
//异常的处理逻辑
System.out.println("呵呵");
}
System.out.println("后续代码!");
}
/*
定义一个方法,方法的参数传递一个文件的路径: d:\\abc.java
在方法中根据文件的路径读取文件
*/
public static void readFile(String path) throws FileNotFoundException,IOException{
//判断路径path是否为null,是null抛出IOException
if(path==null){
throw new IOException("您传递的路径是null");
}
//判断路径path是否为d:\\abc.java,不是抛出FileNotFoundException
if(!"d:\\abc.java".equals(path)){
throw new FileNotFoundException("您传递的路径不是d:\\abc.java");
}
//根据路径读取文件
System.out.println("读取到了d:\\abc.java文件,文件中的内容是abc!");
}
}
8.Objects类中requireNonNull方法(了解)
package com.itheima.demo03Exception;
import java.util.Objects;
/*
java.util.Objects:操作对象的工具类
静态方法:容忍空指针安全的
requireNonNull:判断传递的对象是否为null
如果传递的对象是null,方法内部就会抛出空指针异常
如果传递的对象不是null,则方法内部返回这个对象
public static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
public static <T> T requireNonNull(T obj, String message) {
if (obj == null)
throw new NullPointerException(message);
return obj;
}
*/
public class Demo07Objects {
public static void main(String[] args) {
Person p = new Person();
Person p2 = Objects.requireNonNull(p);
System.out.println(p);//com.itheima.demo03Exception.Person@4554617c
System.out.println(p2);//com.itheima.demo03Exception.Person@4554617c
System.out.println(p==p2);//true
Person p3 = null;
//Person p4 = Objects.requireNonNull(p3);//NullPointerException
Person p4 = Objects.requireNonNull(p3,"您传递的对象是null");//NullPointerException: 您传递的对象是null
System.out.println(p4);
}
}
9.Throwable类中定义的异常处理逻辑(了解)
package com.itheima.demo03Exception;
/*
Throwable类中定义的异常处理逻辑(了解)
仅供参考,我们可以使用处理异常的方式,也可以自己定义异常的处理方式
Throwable类中定义的方法:
String getMessage() 返回此 throwable 的简短描述。
String toString() 返回此 throwable 的详细消息字符串。重写Object类的toStirng方法
void printStackTrace() JVM把异常信息打印在控制台,默认调用就是此方法
Exception类继承了Throwable,所以Exception所有的子类都可以使用这个三个方法
*/
public class Demo08Throwable {
public static void main(String[] args) /*throws Exception*/ {
try {
throw new Exception("异常了!");
} catch (Exception e) {//Exception e = new Exception("异常了!");
//异常的处理逻辑:可以是任意的代码
//System.out.println("哈哈");
//String getMessage() 返回此 throwable 的简短描述。
//System.out.println(e.getMessage());//异常了!
//String toString() 返回此 throwable 的详细消息字符串。重写Object类的toStirng方法
//System.out.println(e.toString());//java.lang.Exception: 异常了!
//System.out.println(e);//java.lang.Exception: 异常了!
//void printStackTrace() JVM把异常信息打印在控制台,默认调用就是此方法,打印的异常信息是最全面的
e.printStackTrace();
/*
java.lang.Exception: 异常了!
at com.itheima.demo03Exception.Demo08Throwable.main(Demo08Throwable.java:15)
*/
}
}
}
10.finally关键字(重点)
finally关键字里边定义的代码,无论程序是否有异常,都会执行
package com.itheima.demo03Exception;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
finally关键字(重点)
作用:
finally关键字里边定义的代码,无论程序是否有异常,都会执行
工作中一般用于资源释放(IO)
格式:
try{
可能产生异常的代码
}catch(定义一个异常相关的变量){
异常的处理逻辑(想怎么写就怎么写)
}
...
catch(定义一个异常相关的变量){
异常的处理逻辑(想怎么写就怎么写)
}finally{
无论是否异常,都会执行的代码
}
注意:
1.finally关键字不能单独使用,必须和try一起使用
2.如果try中出现了异常,会先执行catch中异常的处理逻辑,再执行finally中定义的代码
执行完毕,继续执行try...catch...finally之后的代码
3.如果try中没有出现异常,执行完try中的代码,再执行finally中定义的代码
执行完毕,继续执行try...catch...finally之后的代码
*/
public class Demo09finally {
public static void main(String[] args) throws ParseException {
/*
程序执行流程:
没有异常:A==>C==>D
有异常:B==>C==>D
*/
/*try {
//可能产生异常的代码
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = sdf.parse("2021-1129");
System.out.println("A:"+date);
} catch (ParseException e) {
//异常的处理逻辑
System.out.println("B:"+e.toString());
} finally {
//无论是否异常,都会执行的代码
System.out.println("C:无论是否异常,都会执行的代码");
}*/
/*
程序执行流程:
没有异常:A==>C==>D
有异常:C==>JVM终止程序
*/
try {
//可能产生异常的代码
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = sdf.parse("2021-1129");
System.out.println("A:"+date);
}finally {
//无论是否异常,都会执行的代码
System.out.println("C:无论是否异常,都会执行的代码");
}
System.out.println("D:后续代码!");
}
}
11.异常处理的注意事项(了解)
1).运行时(期)异常
package com.itheima.demo04Exception;
/*
异常的注意事项:
1.运行时(期)异常被抛出可以不处理。
即不捕获(不使用try...catch来捕获处理异常)
也不声明抛出(不使用throws关键声明抛出异常)。
运行时异常,我们无需处理,默认会交给JVM处理==>中断
运行时异常,处理没有意义,处理了也是为了执行后续代码
但是使用数组,超出了数组索引的使用范围,就算我们使用try...catch处理了运行时异常
实际上数组还是越界
这时候我们应该修改代码,不让数组的索引越界,从根本上解决问题
*/
public class Demo01Exception {
public static void main(String[] args) {
//使用try...catch,处理了运行时异常,也是为了执行后续代码,异常本身还存在
/*try {
int[] arr = {10,20,30};
System.out.println(arr[3]);//throw new ArrayIndexOutOfBoundsException("3")
} catch (Exception e) {
e.printStackTrace();
}*/
//在实际工作中:运行时异常修改代码,不让运行时异常出现,从根本上解决异常
int[] arr = {10,20,30};
System.out.println(arr[2]);
System.out.println("后续代码!");
}
}
2).子父类异常的处理
package com.itheima.demo04Exception;
public class Demo02Fu {
public void show01()throws Exception{}
public void show02()throws Exception{}
public void show03()throws Exception{}
public void show04(){}
}
package com.itheima.demo04Exception;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
异常处理的注意事项:
2.子父类异常的处理
a.如果父类的方法抛出了多个异常,
子类重写父类方法时,子类可以抛出和父类相同的异常
子类重写父类方法时,抛出父类异常的子类
子类重写父类方法时,可以不抛出异常
b.父类方法没有抛出异常,子类重写父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出
重点:
父类异常什么样,子类重写父类方法就和父类一样就可以了,无需考虑异常问题
*/
public class Demo03Zi extends Demo02Fu {
//子类重写父类方法时,子类可以抛出和父类相同的异常
@Override
public void show01()throws Exception{}
//子类重写父类方法时,抛出父类异常的子类
@Override
//public void show02() throws NullPointerException { }
//public void show02() throws ArrayIndexOutOfBoundsException { }
public void show02() throws RuntimeException { }
//子类重写父类方法时,可以不抛出异常
@Override
public void show03(){}
//父类方法没有抛出异常,子类重写父类该方法时也不可抛出异常。
//overridden method does not throw 'java.lang.Exception'
//public void show04()throws Exception{}
//此时子类产生该异常,只能捕获处理,不能声明抛出(throws处理异常的方式不能使用了)
public void show04() {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = sdf.parse("2021-1129");
System.out.println("A:"+date);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
3).多个异常使用捕获又该如何处理
package com.itheima.demo04Exception;
import java.util.ArrayList;
/*
异常处理的注意事项:
多个异常使用捕获(try...catch)又该如何处理呢?
1. 多个异常分别处理。
2. 多个异常一次捕获,多次处理。
3. 多个异常一次捕获一次处理。
*/
public class Demo04Exception {
public static void main(String[] args) {
//1. 多个异常分别处理:一个try catch处理一个异常
/*try {
int[] arr = {10,20,30};
System.out.println(arr[3]);
} catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
}
try {
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
System.out.println(list.get(2));
} catch (IndexOutOfBoundsException e) {
e.printStackTrace();
}*/
/*
2. 多个异常一次捕获,多次处理。
一次捕获:把所有的代码写在一个try中
多次处理:一个异常使用一个catch处理
每个catch中,都可以针对异常写特有的处理方式
*/
/*try {
int[] arr = {10,20,30};
//System.out.println(arr[3]);
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
System.out.println(list.get(2));
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("数组索引越界了:"+e);
}catch (IndexOutOfBoundsException e) {
System.out.println("集合索引越界了:"+e);
}*/
//3. 多个异常一次捕获一次处理。
try {
int[] arr = {10,20,30};
//System.out.println(arr[3]);
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
System.out.println(list.get(2));
} catch (Exception e) {
/*
多态
Exception e = new ArrayIndexOutOfBoundsException();
Exception e = new IndexOutOfBoundsException();
*/
e.printStackTrace();
}
System.out.println("后续代码!");
}
}
package com.itheima.demo04Exception;
import java.util.ArrayList;
public class Demo05Exception {
public static void main(String[] args) {
/*
2. 多个异常一次捕获,多次处理。
一次捕获:把所有的代码写在一个try中
多次处理:一个异常使用一个catch处理
每个catch中,都可以针对异常写特有的处理方式
注意:
当多异常分别处理时,捕获处理,前边的类不能是后边类的父类
public class ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException
*/
try {
int[] arr = {10,20,30};
//System.out.println(arr[3]);
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
System.out.println(list.get(2));
}catch (IndexOutOfBoundsException e) {
System.out.println("集合索引越界了:"+e);
} /*catch (ArrayIndexOutOfBoundsException e) {
System.out.println("数组索引越界了:"+e);
}*/
}
}
12.自定义异常(使用)
自定义异常:自己定义一个异常类
1).概述和基本定义格式
package com.itheima.demo05Exception;
/*
自定义异常:
java给我们提供的异常类不够我们使用,就需要我们自己定义一些异常相关的类
注意:
1.自定义异常,一般都是以Exception结尾的,说着这个类是一个异常相关的类(见名知意)
2.自定义异常
a.可以继承Exception:自定义异常就是一个编译期异常
使用:如果在方法内部抛出了编译期异常,那么我们就必须处理这个异常
1).使用throws在方法上声明抛出异常对象,最终抛出给JVM处理
2).使用try...catch自己捕获处理异常
b.可以继承RuntimeException:自定义异常就是一个运行时异常
使用:如果在方法内部抛出了运行时异常,我们无需处理,默认会交给JVM处理(中断)
格式:
public class xxxException extends Exception|RuntimeException{
//定义一个空参数构造方法
public xxxException(){
super(); //调用父类的空参数构造方法
}
//定义一个带异常信息的构造方法
//我们查询异常相关类的源码发现,每个异常类都会定义一个带异常信息的构造方法,把异常信息传递给父类处理
public xxxException(String message){
super(message); //调用父类带异常信息的构造方法
}
}
*/
public class RegisterException extends Exception|RuntimeException{
public RegisterException() {
super();
}
public RegisterException(String message) {
super(message);
}
}
2).自定义异常的使用
a.自定义异常类是编译异常:必须处理
package com.itheima.demo05MyException;
/*
自定义异常:RegisterException 继承 Exception
自定义异常:就是一个编译期异常
*/
public class RegisterException extends Exception{
public RegisterException() {
super();
}
public RegisterException(String message) {
super(message);
}
}
package com.itheima.demo05MyException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
/*
自定义异常的使用
注册案例:
1.定义一个ArrayList集合,存储用户已经注册过的用户名
2.使用Scanner获取一个用户本次输入的注册用户名
3.定一个方法,在方法中判断用户输入的用户名是否已经被注册
a.遍历ArrayList集合,获取每一个已经注册的用户名
b.使用已经注册的用户名和用户本次输入的用户名比较
true:一样,用户名已经被注册了==>抛出一个RegisterException注册异常
false:继续遍历获取用户名比较
c:遍历结束了,还没有找到相同的用户名
进行注册:把用户名存储到ArrayList集合中
提示用户"恭喜您xx名字注册成功!"
*/
public class Demo01Test {
public static void main(String[] args) throws RegisterException {
//1.定义一个ArrayList集合,存储用户已经注册过的用户名
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张三","李四","jack","rose");
//2.使用Scanner获取一个用户本次输入的注册用户名
Scanner sc = new Scanner(System.in);
System.out.println("请输入您要注册的用户名:");
String regName = sc.nextLine();
//调用校验的方法
checkName(list,regName);
}
//3.定一个方法,在方法中判断用户输入的用户名是否已经被注册
public static void checkName(ArrayList<String> list,String regName) throws RegisterException {
//a.遍历ArrayList集合,获取每一个已经注册的用户名
for (String name : list) {
//b.使用已经注册的用户名和用户本次输入的用户名比较
if(name.equals(regName)){
//true:一样,用户名已经被注册了==>抛出一个RegisterException注册异常(编译期异常,必须使用throws或者try...catch处理)
throw new RegisterException("您输入的用户名["+regName+"]已经被注册了!");
}
//false:继续遍历获取用户名比较
}
//c:遍历结束了,还没有找到相同的用户名
//进行注册:把用户名存储到ArrayList集合中
list.add(regName);
System.out.println(list);
//提示用户"恭喜您xx名字注册成功!"
System.out.println("恭喜您用户名["+regName+"]注册成功!");
}
}
b.自定义异常是运行期异常:不用处理
package com.itheima.demo06MyException;
/*
自定义异常:RegisterException 继承 RuntimeException
自定义异常:就是一个运行期异常
*/
public class RegisterException extends RuntimeException{
public RegisterException() {
super();
}
public RegisterException(String message) {
super(message);
}
}
package com.itheima.demo06MyException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
/*
自定义异常的使用
注册案例:
1.定义一个ArrayList集合,存储用户已经注册过的用户名
2.使用Scanner获取一个用户本次输入的注册用户名
3.定一个方法,在方法中判断用户输入的用户名是否已经被注册
a.遍历ArrayList集合,获取每一个已经注册的用户名
b.使用已经注册的用户名和用户本次输入的用户名比较
true:一样,用户名已经被注册了==>抛出一个RegisterException注册异常
false:继续遍历获取用户名比较
c:遍历结束了,还没有找到相同的用户名
进行注册:把用户名存储到ArrayList集合中
提示用户"恭喜您xx名字注册成功!"
*/
public class Demo01Test {
public static void main(String[] args) {
//1.定义一个ArrayList集合,存储用户已经注册过的用户名
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张三","李四","jack","rose");
//2.使用Scanner获取一个用户本次输入的注册用户名
Scanner sc = new Scanner(System.in);
System.out.println("请输入您要注册的用户名:");
String regName = sc.nextLine();
//调用校验的方法
checkName(list,regName);
}
//3.定一个方法,在方法中判断用户输入的用户名是否已经被注册
public static void checkName(ArrayList<String> list,String regName) {
//a.遍历ArrayList集合,获取每一个已经注册的用户名
for (String name : list) {
//b.使用已经注册的用户名和用户本次输入的用户名比较
if(name.equals(regName)){
//true:一样,用户名已经被注册了==>抛出一个RegisterException注册异常(运行时异常,无需处理.默认交给JVM处理)
throw new RegisterException("您输入的用户名["+regName+"]已经被注册了!");
}
//false:继续遍历获取用户名比较
}
//c:遍历结束了,还没有找到相同的用户名
//进行注册:把用户名存储到ArrayList集合中
list.add(regName);
System.out.println(list);
//提示用户"恭喜您xx名字注册成功!"
System.out.println("恭喜您用户名["+regName+"]注册成功!");
}
}
异常总结(重点中的重点):
package com.itheima.demo07Exception;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
异常:程序不正常
throw:在方法中抛出指定的异常对象
运行期异常对象:无需处理,默认交给JVM处理(中断)
编译期异常对象:必须处理
throws:异常处理的第一种方式,把异常对象抛出给方法的调用者处理,最终抛出给JVM(中断)
最终抛给虚拟机,程序中断,无法执行后续代码
try...catch:异常处理的第二种方式,使用try捕获异常对象,把异常对象抛给catch(接住)处理
自己处理了异常,可以执行后续代码
finally:无论程序是否有异常,都会执行finally中的代码
*/
public class Demo01Exception {
public static void main(String[] args) /*throws Exception */{
try {
throw new Exception("长绿毛了!");
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("无论程序是否有异常,都会执行finally中的代码");
}
//ctrl+alt+t
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = sdf.parse("2021-1129");
System.out.println("A:"+date);
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println("后续代码!");
}
}