总结
异常
异常:就是Java中程序的一种错误
Java中异常机制:
表示程序的某个错误,当错误发生的时候,将程序结束,提示在那个位置出现什么错误
Java中异常的体系结构:每种错误就是一个类
Throwable类:java中错误、异常的父类
Error:错误,不能用Java代码处理错误
eg:
VirtualMachineError:虚拟机损坏的错误
StackOverflowError:堆栈溢出
Exception:异常,需要使用Java代码处理错误
1. 编译时异常:编译之前必须处理的异常,强制处理的异常
2. 运行时异常:不强制处理的异常
常见的异常
- 运行时异常
NullPointerException:空指针异常(对象在堆里面没有引用,就直接调用方法)
对象在调用方法或属性的时候需要做非空判断
StringIndexOutOfBoundsException:字符串下标越界的异常
只要操作数组下标,必须要做合法性判断
ArrayIndexOutOfBoundsException:数组下标越界
操作数组先做非空和空数组
ArithmeticException:算术异常
NumberFormatException:数值的格式异常
ClassCastException:类型转化异常,对象向下转型的时候 - 编译时异常
ParseException:转换日期格式的异常
区分编译时异常和运行时异常:
只要异常的父类时RuntimeException就是运行时异常,其他就是编译时异常
异常的处理方式:
-
甩锅式 在方法上抛出异常或者在方法里直接抛出
throws在方法的声明上面抛出异常
只要程序出现抛出的异常,JVM会创建相应对象,再去调用相应的方法来提示错误
在方法体内抛出异常,throw 异常对象public class ExceptionDemo3 { // 声明一个方法 public static void m() throws ParseException { // 抛出异常,异常抛给调用者,thorws // 省略方法体 new SimpleDateFormat("yyyy-MM-dd").parse("2023/12/19"); } public static void mm() throws IOException { } public static void main(String[] args) throws ParseException { // 直接抛给JVM m(); mm(); String str = ""; str.length(); } }
-
背锅式
try{
可能会出现异常的代码
}catch(异常类名 参数名) {
报这种异常错误信息的代码
}.....注意:catch的顺序时先子后父
finally {
处理异常的出口
作用:关闭资源
}public class ExceptionDemo4 { public static void main(String[] args) throws ParseException { try { new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2023-12-19 14:11:20"); return; // 结束方法 System.exit(0); } catch (ParseException e) { throw new RuntimeException(e); } finally { System.out.println("异常处理的出口"); } new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2023-12-19 14:11:20"); } }
自定义异常
写程序执行过程有不满条件情况都是异常,需要自己定义
class 自定义异常的名字(XxxException) extends Exception {
// 自定义编译时异常
书写两个构造方法
一个无参
一个有1个字符串参数的构造方法
}
class 自定义异常的名字(XxxException) extends RuntimeException {
// 自定义运行时异常
}public class AccountStartWithCharException extends RuntimeException { public AccountStartWithCharException() { } public AccountStartWithCharException(String message) { super(message); } }
/** * 自定义的异常:账号不在6-18位就会报这个异常 */ public class AccountSizeException extends Exception { public AccountSizeException() { } public AccountSizeException(String message) { super(message); } }
线程
-
进程:一个应用软件就是一个进程,一大段程序(代码)
每一个进行运行都有独立内存空间
优酷:进程A
腾讯:进程B
快播:进程C
进程的运行相互不干扰 -
线程:一个进程里面独立某个功能就是一个线程,一小段代码
其实软件运行的就是线程
一个进程里面至少有一个线程,也可以有多个线程
线程的运行也是独立,每个线程也有独立运行内存,这个内存时进程的内存 -
线程时怎样执行?
1)、启动线程
2)、线程就是待运行状态
3)、cpu会统计目前内存中有多少个待运行的线程
会将运行时间平均分配给每个待运行的线程
4)、那个线程获得这个时间片,那这个线程就开始执行,直到时间片用完,线程就暂停
注意:在cpu里面同一时间只能运行一个线程 -
为什么软件要设计位多线程?
Java实现多线程的方式
1)、继承Thread类,重写run()
使用多线程public class Play extends Thread{ // Play是多线程 // 重写run():线程获得时间片后执行的代码 @Override public void run() { for (int i = 1; i <= 10; i++) { // 获取当前线程的名字 String name = Thread.currentThread().getName(); System.out.println(name + ":播放视频第" + i + "次"); try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } } } }
/** * 多线程的测试类 */ public class PlayTest { public static void main(String[] args) { // 1、创建线程 Play p1 = new Play(); // 开启一个线程 Thread-0 Play p2 = new Play(); // 开启一个线程 Thread-1 Play p3 = new Play(); // 开启一个线程 Thread-2 // 2、开启线程,start() // p1.start(); // 启动p1线程 // p2.start(); // p3.start(); p1.setDaemon(true); p1.setName("蘋蘋"); System.out.println(p1.isDaemon()); // p1.setPriority(10); // System.out.println(p1.getPriority()); } }
2)、实现Runnable接口,重写run()
/** * 实现Runnable接口,来实现多线程 */ public class Down implements Runnable{ @Override public void run() { for (int i = 1; i <= 10 ; i++) { System.out.println("下载视频第" + i + "次"); } } }
/** * 实现接口创建多线程的测试类 */ public class DownTest { public static void main(String[] args) { // 1、创建Runnable对象 Down d1 = new Down(); // 2、创建线程对象 Thread t1 = new Thread(d1); // 创建第一个线程 Thread t2 = new Thread(d1); // 创建第一个线程 Thread t3 = new Thread(d1); // 创建第一个线程 // 3、启动线程 t1.start(); t2.start(); t3.start(); } }
讲解Thread类中常用的方法
-
常用字段(常量)
线程的优先级:1-10System.out.println("最高优先级:"+ Thread.MAX_PRIORITY); System.out.println("默认优先级:"+ Thread.NORM_PRIORITY); System.out.println("最低优先级:"+ Thread.MIN_PRIORITY);
-
优先级越高获得时间片的概率越大
线程默认优先级都是:5 -
构造方法
Thread():创建默认名字的线程。
Thread(String name):创建一个指定名字的线程
Thread(Runnable target) :根据传入Runnable对象创建线程,线程的名字是默认的
Thread(Runnable target, String name) :根据传入Runnable对象创建线程,线程的名字是指定的 -
常用方法
- getName():获取线程名字
- currentThread() :获取当前线程
- getPriority() :获取线程的优先级
- setPriority(int newPriority) :设置线程优先级
- setName(String name) :设置线程名字
- sleep(long millis):设置线程休眠的时间
- 线程分为:前台线程,后台线程(守护线程)
GC:垃圾回收机制(GC属于后台线程) - isDaemon():判断线程是否位守护线程
- setDaemon(boolean on):设置线程位守护线程
梳理线程
线程的执行流程:
1. 启动线程 2. cpu分配时间片 3. 拿到时间片的线程开始执行(run()的代码) 4. 直到run()里面的代码执行完毕后,线程解结束 交替执行
java中实现多线程的方式:
1. 继承Thread,重写run方法 2. 实现Runnable接口
创建线程,启动线程
Thread常用的方法:
- 获取当前的线程
- 线程休眠
- 获取线程名字
线程的状态:
1. 新建 new Play(); 2. 就绪 new Play().start(); 3. 运行 执行run方法的时候 4. 阻塞 sleep() 5. 死亡(结束) run方法执行完毕
-