一 复习回顾
-
abstract能修饰那些结构?修饰以后有什么特点?
-
修饰类与方法
-
类:不能实例化,需要提供子类染子类进行实例化
-
方法:首先这个方法连括号都没有了,他不是一个完整的方法体了
- 他只是定义了一个功能标准,一定要实现(如果要使用的话)
-
-
接口是否能继承接口,抽象类是否能实现(implements)接口?抽象类是否能继承非抽象类
- 可以,可以,可以
-
声明一个抽象类,并包含抽象方法,测试类中创建一个继承抽象类的方匿名对象?
-
匿名子类对象2
-
-
抽象类和接口有哪些共同点和区别
-
相同点:不能实例化,都可以被继承
-
不同点:抽象类有构造器 接口:没有构造器
抽象类是单继承,接口是多继承
-
5.如何创建静态成员内部类和非成员内部类的对象?
二 异常概述与异常体系结构
①什么是异常
其实就是有些问题代码无法处理(不是逻辑问题和语法问题):
- 客户输入数据格式
- 读取文件是否存在
- 网络是否保持通畅
- …
②异常分类
-
error:
- 就是虚拟机无法解决的严重问题:如JVM系统内部错误,资源耗尽的严重情况。比如:Stack OverflowError 和OOM,一般不编写针对性的代码进行处理
-
Exception:
-
其他异味编译错误或者偶然的外在因素导致的一般性问题,可以使用针对性代码进行处理,例如:
- 空指针异常
- 试图读取不存在的文件
- 网络连续中断
- 数组角标越界
-
常见解决方法:
-
- 遇到错误终止运行
- 编写程序是就会考虑到错误,考虑到错误检测,错误的提示以及错误的处理
- 捕获错误最理想的时候是编译的时候,但是有些错误只有在运行的时候才会出现
-
(1)运行时异常
①NullPointException 空指针异常
public class ExceptionTest {
//NullPointException 空指针异常
@Test
public void test1(){
// int [] arr=null;
// System.out.println(arr[3]);
String str="abc";
str = null;
System.out.println(str.charAt(0));
}
②ArrayIndexOutBoundsException 越界问题
public void test2(){
//ArrayIndexOutBoundsException 越界问题
int [] arr=new int[10];
System.out.println(arr[11]);
String str="abc";
System.out.println(str.charAt(3));
}
③classCastException 类型转换异常
//classCastException 类型转换异常
public void test3(){
Object obj=new Date();
String str=(String)obj;
}
④NumberFormatException 数据转换异常
//NumberFormatException
public void test4(){
/*
正确的情况
*/
String str="123";
int i = Integer.parseInt(str);
// 错误的情况
str="ABC";
int b = Integer.parseInt(str);
}
⑤InputMismatchException 数据类型不匹配
//InputMismatchException
@Test
public void test5(){
Scanner scanner = new Scanner(System.in);
int a=scanner.nextInt();
System.out.println(a);
}
⑥ArithmeticException算数异常
//ArithmeticException 算数异常
public void test6(){
int a=10;
int b=0;
System.out.println(a/b);
}
(2)编译时异常(编译都不能过)
三 子类方法重写的规则
-
重写规则之一
-
子类重写的方法跳出异常类型不大于父类被重写的类型抛出的异常类型
这样的话就会报错,因为父类不可以小于他的子类,不过可以相同
四 异常处理机制一:try-catch-finally(重点)——自我解决机制
- 就是使用大括号将有可能有问题的代码区分开,然后使得它处理简介
1 try catch-finally的使用
try{
可能出现异常的代码
} catch(异常类型1 变量名1){
处理异常的方式}
catch(异常类型2 变量名2){
处理异常的方式}
。。。。
finally{
//一定执行的代码}
①代码举例
@Test
public void test1(){
String str ="123";
str="abc";
try {
int num =Integer.parseInt(str);//这个就不执行,直接抛出
System.out.println("hello --------1");
}catch (NumberFormatException e){//进行错误类型捕获看看是否为NumberFormatException,是就执行相关代码
System.out.println("出现数值转换异常");catch (Exception e){
System.out.println("出现异常");
}
}
System.out.println("hello --------2");
}
}
异常处理方式:
//1.e.getMessage方法
System.out.println(e.getMessage());
//2.e.printStackTrace();可以知道哪个结构是哪个地方出现问题
e.printStackTrace();
![image-20210301194051554](https://i-blog.csdnimg.cn/blog_migrate/cc99ebbfd738f3ca1d0f2627794890e0.png)
总结:
1. finally是可选的
2.使用try将可能出现异常的代码包装起来,在执行的过程中,一旦出现异常,就会生成一个异常类的对象,根据相关内容到catch类中进行匹配,
3. 一旦异常类的对象匹配到摸个catch是,就会进入摸个类中进行catch一旦处理完成,那么就相当于跳出当前结构,不会执行后面的catch(这是指没写finall的情况)
4.catch中的异常关系如果没有子父类关系,那么谁在上面谁在下面都没有关系
5.如果有子父类关系那么父类不能在上面
try -catch结构他是可以嵌套的
2finally解释
- finally是可选的
- 即使finally中说明的是一定会被执行的代码,即使catch中有出现异常了,try中出现return语句,catch中有return语法错误
- 像数据库连接,嵌入输出流,网络编程Socket等资源,JVM是不能自动回收的,我们需要自己手动的对资源进行释放,此时资源的释放,就会声明在finally中。
- try -catch结构他是可以嵌套的
例子一
public void test(){
try {
int a=10;
int b=0;
System.out.println(a/b);
}catch (ArithmeticException e){
//e.printStackTrace();//输出错误信息
//在catch中出现了异常,如果没有finally那么他是没有办法执行后面的语句的
int []arr=new int[10];
System.out.println(arr[10]);
}catch (Exception e){
e.printStackTrace();
}finally {
//一定会执行的代码
System.out.println("我好帅啊!!!");
}
例子二:
@Test
public void methodTest(){
int num= method();
System.out.println(num);
}
public int method() {
try {
int[] arr = new int[10];
System.out.println(arr[10]);
return 1;
} catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
return 2;
} finally {
System.out.println("我一定会被执行");
}
}
![image-20210302092800648](https://i-blog.csdnimg.cn/blog_migrate/1a3bf52a147325954f3502ff36dc1c1b.png)
得出结论**:他的finally后面的代码会比其他的代码先执行,如果finally后面有一个return值,那么返回值就是finally里面的返回值**
例子三:(finall里面还可以嵌套的问题)
public class FinallyTest {
@Test
public void test2() {
FileInputStream fis=null;//声明在外面就可以解决try里面和finally里面声明不一致的情况问题
try {
File file=new File("hello.text");
fis=new FileInputStream(file);
int data=fis.read();
while (data!=-1){
System.out.println((char)data);
data=fis.read();
}
}catch (FileNotFoundException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
finally {
try {
if (fis!=null)--等于null其实就是流都没有打开,就没必要关闭了
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
3.总结:
- 使用try-catch-finally处理编译异常,是指程序编译的时候不报错,但是后面依旧会报错
- 开发中由于运行时异常较为常见,而且我们也不知道什么时候发生,时异我们不会对运行时异常使用try-catch-finally,但是,如果他是编译异常那么我们就需要使用异常处理
五 异常处理机制二:throws(重点)——异常抛出机制
- 就是将问题上报的机制向上寻找解决问题的途径,其实并没有将问题彻底解决
处理方式:throws+异常类型
- throws+异常卸载声明出,指出这个方法执行时,可能抛出的异常类型
- 一旦异常抛出执行时,出现异常依旧会在异常的代码处,生成代码的对象,这个对象如果满足后面的类型的时候,他就会被抛出,后续代码就不再执行了
- 体会:try-catch-finally真正将异常处理了,而throws只是将异常抛给了方法的调用者,没有把方法真正的处理掉
- 开发中如何选择使用throws还是try catch方法?
- 如果父类中被重写的方法没有用法throws的方法处理异常,那么他的子类也不可以用throws去处理哪个异常,如果子类中有异常,那么我们必须要用try-catch-finally的方法去处理异常
- 执行的方法中先后又调用了另外的几个方法,这几个方法使用递进的方式执行的,我们将以这几个方法使用throws的方式进行处理,而执行的方法就考虑使用try-catch-finally的方式进行处理
package Demo03;
import org.junit.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class ExceptionTest2 {
public static void main(String[] args){
try {
method2();
}catch (IOException e){
e.printStackTrace();
}
method3();//所以说只有try catch finally这样只能才能真正解决
}
public static void method3(){
try {
method2();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void method2()throws IOException{
method1();
}
public static void method1() throws IOException, FileNotFoundException {
File file = new File("hello.text");
FileInputStream fis = new FileInputStream(file);
int data = fis.read();
while (data != -1) {
System.out.println((char) data);
data = fis.read();
}
fis.close();
}
}
六 手动抛出异常:throw
关于异常的产生:
① 系统自动生成对象
②手动的生成一个异常对象(throw)
package Demo03;
public class StudentTest {
public static void main(String[] args) {
Student s=new Student();
try {
s.regist(-2);
} catch (Exception e) {
// e.printStackTrace();
System.out.println(e.getMessage());
}
System.out.println(s.toString());
}
}
class Student{
@Override
public String toString() {
return "Student{" +
"id=" + id +
'}';
}
private int id;
public void regist(int id) throws Exception {
if (id>0){
this.id=id;
}else {
//手动抛出一个异常对象
//throw new RuntimeException("数据输入非法");
throw new Exception("输入非法");
}
}
}
七 用户自定义异常类
如何自定义异常类:
- 继承现有的异常结构:Exception,RuntimeException
- 提供全局常量:SerialVersionUID就是相当于标签一样的唯一标识:
- 提供重载的构造器
package Demo03;
/*
*/
public class MyException extends Exception{
static final long serialVersionUID = -7034897190745754939L;
public MyException() {
}
public MyException(String message) {
super(message);
}
}
调用机制:
private int id;
public void regist(int id) throws Exception {
if (id>0){
this.id=id;
}else {
//手动抛出一个异常对象
//throw new RuntimeException("数据输入非法");
throw new MyException("输入非法");
}
}
o03;
/*
*/
public class MyException extends Exception{
static final long serialVersionUID = -7034897190745754939L;
public MyException() {
}
public MyException(String message) {
super(message);
}
}
**调用机制**:
```java
private int id;
public void regist(int id) throws Exception {
if (id>0){
this.id=id;
}else {
//手动抛出一个异常对象
//throw new RuntimeException("数据输入非法");
throw new MyException("输入非法");
}
}
直接调用就好