第八天 异常

异常

概念

  • 指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止。

异常体系

​ Throwable(类)

​ |–Error(不可避免,非代码造成的。比如电脑进水了,电脑冒烟了)

​ |–Exception(编译时期异常,如果不解决就无法生成.class问卷)

​ |–RuntimeException(运行时异常,如果不解决,可以生成.class文件,但是运行时可能报错)

异常分类

  • 运行时异常(只有在运行时我们才知道会发生什么错误)

  • 编译时异常(在编译时就知道他可能会发生什么错误,会报红,必须解决)

运行时异常
* 空指针异常
* 角标越界异常(数组角标,字符串角标,集合角标)
* 类型转换异常 ClassCastException
* 数学异常 1/0
* NoSuchException
* 并发修改异常

编译时异常
*ParseException

处理异常

  • 方式一 交给JVM虚拟机

  • 方式二 自己处理

  • 方式三 交给别人处理

产生异常的2种方式

  • 1.代码写的有问题,不小心造成的。int num = 1/0;//JVM帮我们创建,但是我们只知道会报错,错误提示不友好

  • 2.人为、故意产生一个异常。throw new RuntimeException(“异常提示信息”);使用throw创建异常的好处:发生异常后提示比较友好

对方法的形式参数进行非空校验

  • public static T requireNonNull(T obj) :查看指定引用对象不是null

​ 作用:提高代码的执行效率还有健壮性

源码
public static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
    public  static void registerEmail(String email){
        //对参数进行非空校验,如果参数是null则会报错 
        Objects.requireNonNull(email,"邮箱不能为空");
  
        String s = email.substring(0, email.indexOf("@"));
        System.out.println(s);
    }

异常处理的两种方式

  • 1.在方法上声明throws 表示自己不处理,交个给该方法的调用者处理- - throws 只能写在方法上

​-- throws 后面可以跟多个异常

– 如果编写的代码中会产生多个异常,那么我们可以直接throws Exception

  • try…catch:try捕获异常,如果try中有多个语句,遇到异常,后面的语句不会执行。try…catch代码后面的会执行。注意:try和catch都不能单独使用,必须连用

Throwable的方法

  • printStackTrace();//将异常信息控制台

  • toString();//获取到的是字符串 格式 异常名:异常的提示信息比如 NullPointerException:邮箱不能为空

  • getMessage();//获取到的也是字符串,仅仅获取到了提示信息,比如邮箱不能为空

多异常捕获

面试题

a:请说说final,finally,finalize 的区别?

​ final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。

​ 内部类要访问局部变量,局部变量必须定义成final类型,例如,一段代码……

​ finally是异常处理语句结构的一部分,表示总是执行。

​ finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,调用System.gc()可以提醒垃圾回收器回收垃圾。

b:finally 里面的代码永远会执行吗 ?

​ 不一定,程序在执行fianlly前以外G掉

c: 假如在catch里面有 return,finally里面的代码还能被执行吗 ?

​ 如果能,请问是在 第一个return前, 还是在第一个return后 ?

​ 也许你的答案是在return之前,但往更细地说,我的答案是在return中间执行,请看下面程序代码的运行结果:

​ 考点:

​ 如果代码里有finally,那么finally里面的东西一定会被执行,即使之前return过了

​ 只有return才能设置方法的返回值

 
public static int test1() {
     int x = 1;
     try{
         return x;
     }finally{
         ++x;
     }
}
public static int test2() {
     int x = 1;
     try{
         return x;

     }finally{
         return ++x;
     }
}
public static void main(String[] args) {
    System.out.println(test1());
    System.out.println(test2());
}

d.说说throw和throws的区别

​ throw 是制造异常的一种方式,thorws是处理异常的一种方式

​ throws后面可以跟多个异常,只能定义在方法上,多个异常有逗号隔开

​ throw 只能跟一个异常对象

private static void d() throws Exception {
	throw new Exception();
}

自定义异常编写步骤

  • 创建一个类,继承Exception
  • 添加构造方法

自定义工具类

  • 1.创建包,工具类一般放在utils包下
  • 2.创建类
  • 3.构造方法私有化
  • 4.编写方法,所有的方法都要被static修饰

练习

编写代码模拟用户注册,如果用户名已经存在,抛出自定义异常,异常信息显示:用户名已经被注册

public static void main(String[] args) throws Exception{
        ArrayList<String> list = new ArrayList<>();
        System.out.println("输入要添加的人名:");
        Scanner sc = new Scanner(System.in);

        while (true){
            String input = sc.nextLine();
            regest(list,input);
            System.out.println("当前系统里的人有:"+list);
        }
    }
    private static void regest(ArrayList<String> list,String str) throws Exception{
        if(list.contains(str)){
            throw new  RuntimeException("您注册的用户名已经存在");
        }else {
            list.add(str);
        }
    }

异常注意事项

  • try…catch…catch 这种异常处理方式,要求多个catch中的异常不能相同,并且若catch中的多个异常之间有子父类异常的关系,那么子类异常要求在上面的catch处理,父类异常在下面的catch处理。
  • 运行时异常被抛出可以不处理。即不捕获也不声明抛出。如果finally有return语句,永远返回finally中的结果,避免该情况.
  • 如果父类抛出了多个异常,子类重写父类方法时,抛出和父类相同的异常或者是父类异常的子类或者不抛出异常。
  • 父类方法没有抛出异常,子类重写父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出

线程

并行与并发

  • 并发:指两个或多个事件在同一个时间段内发生。(同一时刻,只能有一件事)
  • 并行:指两个或多个事件在同一时刻发生(同时发生)。

进程:

  • 进程:是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创
    建、运行到消亡的过程。(数据从硬盘到内存的通道)

线程

  • 线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。(数据从内存到CPU的通道)

线程调度

  • 分时调度(时间片轮转)
    所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间
  • 抢占式调度
    优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性),Java使用的为抢占式调度。

##创建线程的第一种方式

  • 定义Thread类的子类,并重写该类的run()方法,该run()方法的方法体就代表了线程需要完成的任务,因此把run()方法称为线程执行体。
  • 创建Thread子类的实例,即创建了线程对象
  • 调用线程对象的start()方法来启动该线程
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值