Day05 异常及其处理、多线程概念

Day 05

第一章 异常

1.1 什么是异常

​ 异常指的是程序在运行或者编译过程中,遇到的非正常的情况,最终会导致java虚拟机运行的停止。

异常不等同与语法错误,语法错误在编译阶段就无法通过

1.2 异常的体系

​ 异常的根类是java.lang.Throwable,它有两个子类,java.lang.Errorkava.lang.Exception

  • Throwable 我们说的异常,通常来说就是指Throwable异常,这类异常可以t通过修改代码来处理,且必须处理,否则会让程序运行停止。
    • 编译时期异常(checked) 如日期的格式化异常
    • 运行时期异常(runtime) 如数组越界
    • throwable的常用方法:
      • public void printStacktrace() 打印异常的详细信息
      • public String getMessage()获取发生异常的原因
  • Error 异常是无法处理的,只能尽量避免
    • Error的原因可能是内存溢出、或是系统奔溃,无法处理
      在这里插入图片描述

1.3异常的产生过程解析

public static void main(String[] args) {
		int [] arr = {1,2,3,4,5,6,7};
		getSum(arr,7);
		}	
	public static int getSum(int [] arr,int n ) {
		return arr[n];
	}

在这里插入图片描述

​ 首先在调用getSum方法时出错 (1),由于它没有对异常进行处理,创建了一个异常对象,并将其传回main()中调用它的方法处(2),但是main()中也没有处理异常的机制 (3),异常继续传递给JVM(java虚拟机),JVM收到异常后,把异常对象的名称、内容、位置显示在屏幕上,并使程序运行停止;

​ 箭头处为异常类型,因为这个异常是数组越界,是java中已知的异常类型,框中的7代表了引发异常的原因。

第二章 异常的处理

2.1 抛出异常:throw

thorw关键字用来抛出异常对象,在方法内部使用

抛出异常的步骤:

  • 新建一个异常对象,封装一些信息,如一些提示语句

  • 用throw关键字将它抛出给调用者

    格式throw new 异常类型名(参数);

throw new ArrayIndexOutOfBoundsException("数组越界");
throw new NullPointerException("空指针异常")

异常的处理方法:

  • 捕获(可以处理时,采用 try-catch 包裹可能出现异常的语句)
  • 抛出(无法处理的时候) throw
public static void main(String[] args) {
		int [] arr = {1,2,3,4,5,6,7};
		getSum(arr,7);
		System.out.println("end");
		}		
	public static int getSum(int [] arr,int n ) {
		if(n>= arr.length) {
			throw new ArrayIndexOutOfBoundsException("数组越界啦");
		}
		return arr[n];
	}//Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 数组越界啦

2.2 Objects非空判断

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

它的源码:对null进行了抛出异常。

public static <T> T requireNonNull(T obj) {
    if (obj == null)
      	throw new NullPointerException();
    return obj;
}

但是Object的一些静态方法,对空指针是容忍的,如equals方法。

2.3 声明异常throws

  • 异常出现后,如果没有被捕获,则此方法必须声明异常throws,throws用在方法上,throw用在方法中,将异常抛出给调用者。

    关键字throws运用于方法声明之上,用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常(抛出异常,可以一次抛出多个).

格式:

修饰符 返回值类 方法名(参数) throws 异常类型1,异常类型2

public static void main(String[] args)throws ArrayIndexOutOfBoundsException {
		int [] arr = {1,2,3,4,5,6,7};
		getSum(arr,7);
		System.out.println("end");
	}
	public static int getSum(int [] arr,int n )throws ArrayIndexOutOfBoundsException,NullPointerException {
		if(n>= arr.length) {
			throw new ArrayIndexOutOfBoundsException("");
		}
		System.out.println("dsaasdasd");
		return arr[n];
	}

2.4 捕获异常 try catch

try catch只能配合使用,不能单独使用,但是可以一个try,有很多catch。

public static void main(String[] args)throws ArrayIndexOutOfBoundsException {
		int [] arr = {1,2,3,4,5,6,7};
		try{int b = arr[7];
		}catch(ArrayIndexOutOfBoundsException s){
			System.out.println("抓住了");
		}
		System.out.println("结束");
		}	

输出结果为:抓住了

​ 结束

​ 异常如果被catch捕获后(catch到,即使此时catch里面没有语句块对异常进行操作,例如将上述代码改成空的catch块,结果依然会输出 : 结束),之后的语句会继续进行,直至程序运行结束或者是碰到另一个异常。

2.5 finally代码块

​ 程序在遇到异常时,会发生跳转,导致某些程序不执行,finally代码块在运行过程中,一定会被执行(不管异常是否出现,是否捕获)。

当只有在try或者catch中调用退出JVM的相关方法,此时finally才不会执行,否则finally永远会执行。

应用场景:打开某些文件流,不管运行是否正常,最终都需要关闭的时候。

格式:try{…}catch{…}finally{…}

public static void main(String[] args)throws ArrayIndexOutOfBoundsException {
		int [] arr = {1,2,3,4,5,6,7};
		try{int b = arr[7];
		}catch(ArrayIndexOutOfBoundsException s){
			System.out.println("抓住了");
		}
		finally {
			System.out.println("执行了finally");
		}
		System.out.println("结束");
		}	
  • 上面的代码,三个输出都会执行

  • 如果此时try中内容改为 int b = arr[5];输出结果为:执行了finally

    ​ 结束

如果finally代码块中包含return关键词,会影响程序的运行,覆盖其他的return,例如像判断两个对象是否相等,如果相等则返回1,不相等返回-1,而在finally语句块加上return -1,则永远会返回-1。

2.6 异常注意事项

  • 在try中,一旦遇到异常,即便后面被成功捕获了,try中异常后面的语句也不会被执行

  • 对于运行期异常RuntimeException,被抛出时可以不处理。既不捕获也不声明抛出。而对于编译异常则必须声明或是用try catch包围它。

  • 当一个父类的一些方法抛出一些异常,一个类继承自它,重写这些方法时,不可以抛出更多异常,但是可以少抛,或者不抛出。父类方法如果没有抛出异常,子类重写该方法时,不可以抛出异常,只能用try-catch捕获。但是子类的构造方法,可以比父类构造方法抛出更多的异常

  • 采用try catch捕获异常是,catch里面的异常类型必须是子类异常在前,父类异常在后,如果子类在后,会被父类异常的catch所屏蔽

  • 异常处理有三种方式:

    • 一次捕获一次处理 try{…} catch{…}
    • 一次捕获,多次处理(最常用):try{…}catch{…1…}catch{…2…}…catch{…n…}
    • 多次捕获,多次处理:很多try,很多catch

第三章 自定义异常类

​ 根据自己的需求,定制所需异常类。如建立一个学生类,当学生的年龄小于0时抛出异常,但是这种异常没有在JDK内部定义。

  1. 自定义一个编译期异常: 自定义类 并继承于java.lang.Exception
  2. 自定义一个运行时期的异常类:自定义类 并继承于java.lang.RuntimeException
public class Day05 {
	private static String [] a = {"first","second","third"}	
	public static void main(String[] args) {
		try {
			add("first");
		}catch(MyException s) {
		System.out.print("抓住了  ");
		}
		System.out.println("运行结束");
	}
	public static void add(String name) throws MyException {
		for(String str : a) {				
			if(str.equals(name)) {
				throw new MyException("已经被注册了");
			}
		}
		System.out.println("注册成功");
			}		
		}
//运行时期异常则应 extends RuntimeException
class MyException extends Exception{
	public MyException() {		
	}
	public MyException(String name) {
		super(name);
	}
}

//抓住了 结束了

第四章 多线程

4.1 并发与并行

  • 并发指的是许多任务在一时间段内被执行
  • 并行指任务在同一时刻同时进行

在CPU处理器中,一个内核在每个瞬间可以执行一段程序,对于单核的CPU无法进行并行计算,只能进行并发计算,核数越多,能够并行处理的程序也就越多。

4.2 线程与进程

  • 进程 :是指一个内存中运行的应用程序,每个进程都有属于自己的独立空间,一个程序至少运行一个进程;进程是系统运行程序的基本单位

    例如任务管理器,谷歌浏览器运行后,存在若干个进程

  • 线程:进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。拥有多个线程的应用程序,称为多线程应用程序

  • 线程调度的类型:

    • 分时调度 :即每个线程占用CPU的时间相同,轮流使用
    • 抢占式调度:根据线程的优先级来确定使用CPU的顺序,如果优先级相同,则再同级中随机取一个线程运行(线程的随机性)。

​ 我们在使用软件的时候不存在只能操作一种软件的情况,而实际上CPU的一个核只能在一瞬间进行一个进程,之所以宏观上我们认为很多软件能同时进行的原因是,一个核心会不断地在各个线程之间切换,时间非常非常短,从宏观上看,像是多个软件一起在运行。

4.3 创建线程类

Java中代表线程的是java.lang.Thread类,所有的线程对象,必须是Threa类及其子类的实例。

每个线程的作用是完成一定的任务,实际上就是执行一段程序流即一段顺序执行的代码。Java使用线程执行体来代表这段程序流。

创建与启动多线程的步骤:

  1. 自定义线程类,继承自Thread,重写run()方法,run()方法代表了线程要完成的任务—线程执行体
  2. 创建线程对象,通过调用对象的start()方法来启动run()
    • 采用Thread中public final String getName()的方法,可以获得该线程的名字
public class Day05 {	
	public static void main(String[] args) {
		NewThread newt = new NewThread("新线程");
		newt.start();
		for(int i = 0; i<15;i++) {
			System.out.println("这是main线程"+i);
		}	
	}
}
class NewThread extends Thread{
	private String name;
	public NewThread(String name) {
		super(name);		
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		for(int i =0;i<15;i++) {
			System.out.println("这是: "+getName()+i);
		}
	}	
}

//输出结果中两种线程的结果会交替出现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值