1、异常-概念及作用
1)、异常:程序运行时JVM遇到无法处理的数据或表达式
2)、JVM遇到这种异常,通常会在控制台打印异常信息,然后结束掉程序,不进行下面的程序
3)、“异常处理”就是允许程序遇到这段异常时,可跳过这段代码,继而进行下面的代码
需要在编写代码前,就预知会产生这样的异常,从而做出预先的处理
2、异常-异常产生的过程解析
1)、JVN执行到有异常的代码;
2)、JVM要识别到这样的异常;
3)、JVM到类库中找到描述这个异常的”异常类”,并创建对象;
4)、判断代码中是否希望捕获这种异常
–是:执行捕获异常的代码
–否:控制台打印异常信息,结束程序(不希望这样)
3、异常-Java异常体系结构及分类
Throwable(异常的顶层父类):
1)、Error
:无法处理,不希望程序捕获
2)、Exception
:可以处理,希望程序捕获的异常
RuntimeException(运行时异常):Java不要求强制捕获这种异常,可以通过判断进行避免
除RuntimeException外的其他异常(编译器异常):Java要求必须强制捕获并处理,否则无法编译通过,这种异常无法通过判断进行避免
4、异常处理-基本方式try…catch语句及执行流程
语法:
try{
//可能出现异常的代码,出现异常时,后面代码不会再继续执行,转而执行catch中的代码
}catch(异常类名 变量名){
//如果try中出现了异常类名的异常,这里会进行捕获
//出现异常后的处理代码
}
代码:
public static void main(String[] args) {
updateStudent();
}
public static void updateStudent(){
Scanner sc = new Scanner(System.in);
while(true) {
System.out.println("请输入学号:");
try {
int stuNo = sc.nextInt();
System.out.println("你输入的学号是:" + stuNo);
break;//正常情况,结束循环
} catch (InputMismatchException e) {
System.out.println("你的输入有误!");
sc = new Scanner(System.in);
}
}
System.out.println("后续代码....");
}
执行流程图:
5、异常处理-常见的几种异常
1)、空指针异常:NullPointerException
:运行时异常
String s = null;
System.out.println(s.length());//编译通过,运行时抛出NullPointerException
要做非空判断,在开发时,要在方法返回时做非空判断(代码会更加健壮)
2)、数组下标越界异常:ArrayIndexOutOfBoundsException
:运行时异常
int[] arr = {1,2,3};
System.out.println(arr[3]);//产生异常,没有3这个索引
3)、数字转换异常:NumberFormatException
:运行时异常
String str = 12a;
int a = Integer.parseInt(str);//产生异常
4)、算术运算异常:ArithmeticException
:运行时异常
int a = 9;
int b = 0;
c = a/b;//产生异常
5)、转换异常:ParseException
:编译期异常,必须捕获,否则编译会异常
String str = "2018-08-08";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try{
Date date = sdf.parse(str);
}catch(ParseException e){//必须对异常进行捕获
.....
}
6、异常处理-try..catch…catch语句及执行流程
老中医Exception必须放在其他具体异常后面
执行流程图:
7、异常处理-声明抛出异常throws
public static void main(String[] args) {
int[] arr = {432, 432, 43, 253};
try {
System.out.println("总和:" + sum(arr));
} catch (NullPointerException e) {
System.out.println("调用方法,接收到一个异常....");
}
System.out.println(sum(null));
}
public static int sum(int[] arr) throws NullPointerException,
ArrayIndexOutOfBoundsException,ArithmeticException {//抛出异常在方法调用处就要用try...catch进行捕获
int sum = 0;
for (int n : arr) {
sum += n;
}
return sum;
}
注意:如果throws后面的是“编译期异常”,调用的代码必须要使用try…catch…或者继续抛出,否则编译错误。如果throws后面的是“运行时异常”,调用处可以不处理,编译可以通过,但不建议。
8、异常的处理-抛出异常对象throw
public static void main(String[] args) {
int[] arr = {432, 432, 43, 253};
try {
System.out.println("总和:" + sum(null));
} catch (NullPointerException e) {
System.out.println("调用方法,接收到一个异常....");
System.out.println("异常信息:" + e.getMessage());
}
}
public static int sum(int[] arr) {
int sum = 0;
if (arr == null) {
throw new NullPointerException("哥们,你给我传了一个空指针,你太坏了....");
}
for (int n : arr) {
sum += n;
}
return sum;
}
注意:如果throw抛出的是一个“运行时异常”,调用处可以不处理,但是不建议;如果throw抛出了一个“编译期异常”,方法声明处必须显示的使用throws声明此异常,调用处也必须处理,否则编译错误;
9、throws和throw的差别
throws:表示“声明”此方法可能会产生某种异常,如果产生,请JVM将此异常对象抛给调用者。如果没有产生异常,则正常执行完毕。
public static void sum() throws NullPointerException{
...
}
throw:表示立即“抛出一个异常对象”
public static void sum(){
if(...){
throw new NullPointerException("...");
}
}
方法throw异常对象,就是为了程序在执行流程中,调用方法时产生异常后chatch异常,进而进行捕获到异常后的处理代码(简单的说就是告诉执行流程,这个方法异常了,你处理下 ps:这个异常是可以自定义发生什么才抛出什么异常)
10、异常的处理-Objects类的非空判断
class Student{
private String name;//要求姓名不能为:null
....
public Student(String name){
/*
if(name == null){
throw new NullPointerException("...");
}
if(...){
}*/
this.name = Objects.requireNonNull(name);//省去一个非空判断
}
}
main(){
Student stu = new Student("张三");
Student stu2 = new Student(null);
}
11、异常的处理-try…catch…finally语句
在try…catch中先执行finally再进行return
public static void main(String[] args) {
String s = show();
System.out.println("返回值:" + s);
}
public static String show(){
try {
System.out.println("1.打开文件");
System.out.println("2.读取文件--出异常" + (10 / 0));
return "呵呵呵";
} catch (Exception e) {
System.out.println("异常了....");
return null;
}finally {//无论是否有异常,永远在return前执行
System.out.println("3.关闭文件");
}
}
12、自定义异常-概述
当类库中没有我们需要的异常类时,可以自定义一个异常类:
class Student{
private int age;
public void setAge(int age){
//假如我们要求年龄必须在15到50之间
if(age < 15 || age > 50){
throw new 自定义异常();
}
this.age = age;
}
}
13、自定义练习:
自定义异常类:继承Exception或者其子类(RuntimeException或非RuntimeException(建议使用,强制对异常进行抛出))
添加一个String参数的构造方法,用于设置“异常信息”
异常类:
public class AgeException extends Exception{
public AgeException(String msg) {
super(msg);//调用父类的构造方法
}
}
使用异常类对对象类内容加以限制
public class Student {
private int age;
public void setAge(int age) throws AgeException {
if (age < 15 || age > 50) {
throw new AgeException("年龄错误,必须在15到50岁之间!");
}
this.age = age;
}
}
测试类:
public class Demo {
public static void main(String[] args) {
Student stu = new Student();
try {
stu.setAge(100);
} catch (AgeException e) {//捕获异常执行下面的代码
System.out.println("异常信息:" + e.getMessage());
}
}
}
13、多线程-进程与线程
1)、进程:操作系统的概念,一个独立运行的程序,就是一个进程;
2)、线程:线程是由进程创建的,一个进程可以创建任意多的线程,每个线程都包含一些代码,线程中的代码会同主线程或其他线程同时运行;
3)、多进程:某个时间段内,同时运行多个程序;
4)、多线程:一个程序可以同时启动多个线程,也就是多段代码可以同时运行,提高程序的运行效率
单线程:只能做一件事
需要程序能够同时做多件事,就要制作多线程程序
14、多线程-并发与并行
1)、并行:多个线程同时开始运行;
2)、并发:多个线程同时访问同一个资源(CPU)。
15、多线程-创建线程类-继承Thread及匿名对象的方式
1)、制作多线程程序,在设计阶段就要确定(那些代码需要独立的运行起来,从而制作线程类)
2)、创建多线程步骤:
–定义线程类,继承Thread
–重写run()方法
–启动线程
创建一个线程对象;
调用对象的start()方法启动线程;
线程类:
public class MyThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("从网络接收外部数据....");
}
}
}
在测试类中启动线程:
public static void main(String[] args) {
//先启动线程
MyThread t = new MyThread();
t.start();//启动线程后,主方法继续向下运行
for (int i = 0; i < 1000; i++) {
System.out.println("从控制台接收数据.....");
}
}
16、多线程-创建线程类-关于线程的几个说明
1)、匿名内部类实现线程:
new Thread(){
public void run(){
for (int i = 0; i < 1000; i++) {
System.out.println("从控制台接收数据.....");
}
}
}.start();
2)、重写的是run()方法,但是在启动线程时是使用start()方法
3)、对于一个线程对象,只能调用一次start()方法,不能多次调用(编译时能通过,但是运行时会报错)
复习
[ ] 能够辨别程序中异常和错误的区别
Error错误:例如:内存溢出,异常中不进行捕获的重大错误
Exception异常:我们希望程序进行捕获处理的,进而使程序可以继续进行下去
[ ] 说出异常的分类
运行时异常(RuntimeException):程序可以不进行处理
非运行时异常:程序必须进行捕获处理的异常,处理之后程序菜能运行下去
[ ] 说出虚拟机处理异常的方式
执行带存在异常的代码
JVM识别异常
JVM在类库中寻找对应异常类,创建对象
判断代码是否catch这个异常:
catch到了:执行catch中的代码;
没有cahtch到:在控制台打印异常信息,结束程序
[ ] 列举出常见的三个运行期异常
空指针异常NullPointerException
数组下边越界异常ArrayIndexOutOfboundsException
运算异常ArithmeticException
[ ] 能够使用try…catch关键字处理异常
try{ //会出现异常的代码 }catch(异常类名 变量名){ //捕获异常后的处理代码 }
[ ] 能够使用throws关键字处理异常
public static void show() throws Exception{}
[ ] 能够自定义异常类
public calss myException extends Exception{ public myException(String str){ super(str) } }
[ ] 能够处理自定义异常类
class Person{ int a = 0; public void addA(int a){ Scanner scanner = new Scanner(System.in); a = scanner.nextInt(); if(a == 0){ threw new myException("a不能为零") } } }
测试:
Person people = new Person(); try{ people.addA(0) }catch(myException e){ System.out.println(e.getMessage()); }
[ ] 说出进程的概念
操作系统中运行的一个程序
[ ] 说出线程的概念
一个进程可以由多个线程组成
[ ] 能够理解并发与并行的区别
1).什么是并行:多个线程同时开始运行;
2).什么是并发:多个线程同时访问同一资源(CPU)。
[ ] 能够开启新线程
创建线程类
class MyThread extends Thread{ public void run(){ //线程开始时要做的事儿 } }
测试类中启动线程:
MyThread m = new MyThread();
m.start();