一、异常
1、1Throwable根目录下的异常
根类java.lang.Throwable
,其下有两个子类:java.lang.Error
与java.lang.Exception
区别为:
Error:严重错误Error,无法通过处理的错误,只能事先避免,好比绝症。(例如电脑内存不足)
Exception:表示异常,异常产生后程序员可以通过代码的方式纠正,使程序继续运行,是必须要处理的。
Throwable中的常用方法:
public void printStackTrace()
:打印异常的详细信息。包含了异常的类型,异常的原因,还包括异常出现的位置,在开发和调试阶段,都得使用printStackTrace。
public String getMessage()
:获取发生异常的原因,提示给用户的时候,就提示错误原因。
1、2异常的分类
编译时期异常:Exception。在编译阶段会报错的异常,需要强制处理,否则不能执行程序。其中包含:
ParseException(解析异常)、
IOException( I/O 异常)、
FileNotFoundException(文件打开异常)
运行时期异常:RuntimeException(unchecked)。在编译时不会报错,不用强制处理,运行时才有可能出现错误。这类异常不是必须处理的。其中包含:
NullPointerException(空指针异常)、
IndexOutofBoundsException(数组索引越界异常)、
ArithmeticException(算术运算异常)、
NumberFormatException:(数字格式异常)
1、3 throw关键字用法
throw: 就是程序运行过程中,产生一个异常,程序会中断执行,一般用于方法内
格式:throw 异常对象
throw new NullPointExtion();//空指针异常的例子
throw new FileNotFoundException();//编译异常的例子
1、4 throws处理异常(甩锅)
如果是运行异常,我们可以不用处理,但如果是一个编译异常,我们必须要处理,一下为两周处理方案:
1、throw(甩锅)
2、try-catch(自己处理解决)
关键字throws运用于方法声明之上,用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常(抛出异常)
//格式:修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2,…{ }
//如果定义功能时有问题发生需要报告给调用者,可以通过方法上使用throws进行声明
public static void read(String path) throws FileNotFoundException{
if(!path.equals("a.txt")){ //如果不是"a.txt"文件
// 假设,如果不是a.txt则认为该文件不存在,是一个错误,也就是异常throw
throw new FileNotFoundException("文件不存在!")
}}
注:
1、throw处理异常时,可以同时处理多个异常,可在throw后边直接写多个异常类并用逗号隔开
1、5 try-catch处理异常
try-catch的方式就是捕获异常:对异常有针对性的语句进行捕获,可以对出现的异常进行指定的处理
try-catch捕获异常语法格式:
try{
编写可能会出现异常的代码
}catch(异常类型 异常对象){
处理异常的代码
}
try {
if (name.contains("*")) {
throw new ParseException("非法名称", 0);
}
System.out.println("没有产生异常:ParseException");
}catch (ParseException e) {
System.out.println("处理了:ParseException");
}
注意:
1、如果有多个异常,多次使用catch进行捕获
2、如果异常存在继承关系,catch时一定要把父类异常放到子类后边
3、当异常处理后,try-catch后边的代码可以正常执行
1、6 finally关键字(保证特定代码最终一定执行)
finally:有一些特定的代码无论异常是否发生,都需要执行。另外,因为异常会引发程序跳转,导致有些语句执行不到。而finally就是解决这个问题的,在finally代码块中存放的代码都是一定会被执行的
语法:try—catch—finally:try语句会打开某些资源块,需要在用完之后最终关闭它,finally不能单独使用
格式:
try{}
catch(){}
finally{ 最终要执行的代码 }
try {
read("a.txt");
} catch (FileNotFoundException e) {
e.printStackTrace(); // 打印异常信息
} finally {
System.out.println("不管程序怎样,这里都将会被执行。");
}
System.out.println("over");
//我们 当前的这个方法中 有异常 有编译期异常
public static void read(String path) throws FileNotFoundException {
if (!path.equals("a.txt")) {//如果不是 a.txt这个文件
//假设,如果不是a.txt则认为该文件不存在,是一个错误,也就是异常throw
throw new FileNotFoundException("文件不存在");
}
}
异常注意事项
1、如果父类抛出了多个异常【编译时异常】,子类覆父类方法时,只能抛出【相同的异常或者是他的子集】
2、父类方法没有抛出异常,子类覆盖父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出
1、7自定义异常
自定义异常的意义:为了满足业务需要,(自带JDK中的异常类型有限)
自定义异常的方法:创建一个类,继承异常类,快捷键构造空参和message参即可
try {
register("王健林");
} catch (RegisterException e) {
String message = e.getMessage();
System.out.println("不好意思出错了:" + message);
}
System.out.println("使用了某个功能");
public static void register(String name) throws RegisterException {
List<String> names = new ArrayList<>();
Collections.addAll(names, "王思聪", "蔡徐坤", "吴亦凡");
if (name.length() < 5) {
throw new RegisterException("用户名太短,需要5个以上");
}
if (!names.contains(name)) {
names.add(name);
System.out.println("恭喜注册成功 = " + names);
} else {
throw new RegisterException("用户名重复已存在");
}}
自定义异常:
public class RegisterException extends Exception {
//alt+Insert快捷构造空参和message参数
public RegisterException() {
}
public RegisterException(String message) {
super(message);
}
}
二、多线程的初步了解
2、1并发与并行、线程与进程
并发:两个或多个事件在同一个时间段内发生(宏观角度同时发生,微观上交替执行)
并行:两个或多个事件在同一时刻发生(真正意义上的同时处理)
进程:是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创建、运行到消亡的过程
线程:进程内部的一个独立执行单元,一个进程可以并发运行多个线程
注意:Java程序里边至少包含两个线程,一个是main方法,一个是垃圾回收机制。由于线程开销比进程开销小得多,在开发多任务运行的时候,考虑创建多线程,而不是多进程。
2、2创建线程类
创建子线程并启动的步骤:
1、创建类继承Thread,重写run方法
2、创建线程对象
3、main方法内创建线程对象,然后调用start方法启动线程
public static void main(String[] args) {
MyThread mt = new MyThread();//main方法内创建子线程对象
mt.start();//调用start方法启动子线程
for (int i = 0; i < 100; i++) { //main线程
System.out.println("小强"+i);
}}
public class MyThread extends Thread { //创建类继承Thread(自定义线程类/子线程)
@Override
public void run() { //重写run方法
for (int i = 0; i < 100; i++) {
System.out.println("旺财"+i);
}}}