标签:提示 子集 父类 index row xtend objects 集合 null
异常,线程
一.异常
1.什么是异常
java程序中出现的不正常显现
2.异常的继承体系
面向对象语言中异常就是用类来表示
(万物皆对象)每个异常都是一个对象
异常的根类:Throwable
子类1:Error,被称为错误类(操作系统本身有错误,程序员不能避免)------内存溢出,系统崩溃
子类2:Exception,被称为异常类
3.异常类中常用的三个方法
-public void printStackTrace();//打印异常的详细信息
包含了异常的类型,异常的原因,还包括异常出现的位置,在开发和调试阶段,都得使用printStackTrace。
-public String getMessage();//获取发生异常的原因
提示给用户的时候,就提示错误原因
-public String toString();//获取异常的类型和异常描述信息(不用)
4.异常的分类:
i.编译时异常
编译时如果异常出现就会报错
是Exception本身以及子类(RuntimeException除外)
ii.运行时异常
编译时不报错,运行时报错
就是RuntimeException本身以及它的子类
5.异常产生过程
JVM发现了一个异常,数组做大下标是2,但是我们要访问3
创建一个异常对象(代表这种异常)
new ArrayIndexOutOfBounds(3)
把这个异常对象抛出去(不管)
throw new ArrayIndexOutOfBounds(3)
最终又到了:JVM
JVM拿到异常对象之后:
处理异常:终端处理
立刻停止程序
把异常对象的所有信息打印到控制台。
列举出常见的三个运行时异常:
ArrayIndexOutOfBoundsException 数组下标越界(运行时)
NullPointerException 空指针引用异常
ClassCastException 类型强制转换异常
Animal an=new Dog();//new Cat();
Cat cc=(Cat)an;
ParseException 编译时异常
====================================================
IllegalArgumentException - 传递非法参数异常。
ArithmeticException - 算术运算异常
ArrayStoreException - 向数组中存放与声明类型不兼容对象异常
NegativeArraySizeException - 创建一个大小为负数的数组错误异常
NumberFormatException - 数字格式异常
SecurityException - 安全异常
UnsupportedOperationException - 不支持的操作异常
注意:
JVM默认处理异常的机制:终断处理
二.异常处理
1.抛出异常关键字throw
throw作用:抛出异常对象(动词)
throw格式:
throw new XxxException(异常的信息)
2.Objects类中提供的非空判断方式:
只要我们定义的方法,有引用类型作用参数,那么第一件必须是判空
public static<T> requireNonNull(T obj)检查指定的对象引用不是null。
3.遇到异常的2种处理方式*******************
throws声明抛出异常(不处理)
使用格式:
public 返回值类型 方法名() throws XxxException{
//内部可能会抛出异常
}
作用:给方法做声明,告诉该方法的调用者,这个方法内部可能抛出某种异常,要求调用者自己处理
try.catch捕获异常
格式:
try{
可能出现异常的代码
}catch(XxxException e){//捕获异常时,必须是可能抛出异常的类型 或者 其父类类型
//处理异常
e.printStackStrace();
}
//下面代码可以照常运行
4.【扩展1】catch代码块中三种常见的处理方式
a.直接打印 调用 异常对象.printStackTrace();
b.记录日志(Log4J ---log for java)
c.转成其他异常继续抛出
5.【扩展2】多个异常如何捕获处理
try{
可能出现异常的代码
假设:可能出现 异常1,异常2,异常3
异常1 继承了 异常2
异常3和 异常1 异常2 没有直接关系
}
a.换个异常 挨个处理
try{
代码段1(可能出现异常1)
}catch(异常1 e){
}
try{
代码段2(可能出现异常2)
}catch(异常2 e){
}
..........
b.比较标准的处理方式:
所有异常一起try,多个catch
try{
可能出现异常的代码
}catch(异常1 e){
}catch(异常2 e){
}catch(异常3 e){
}
如果多个异常之间没有子父类关系,那么顺序随意
如果其中两个异常有子父类关系,那么保证子类异常写前面,父类异常写后面,或者只写父类异常。
e.开发中最常用的:
所有异常一起try,一个catch
try{
可能出现异常的代码
}catch(Exception e){
此处异常应该写三个异常的共同父类,如果不知道那么直接写Exception
}
6.finally代码块
finally:最终的,最后的
和try..catch一起使用
格式:
try{
可能有异常的代码
}catch(异常类型 变量名){
处理异常的代码
}fimally{
必须执行的代码
一般用来写 释放资源的代码
如果没有资源需要释放,那么可以省略finally代码块
}
7.异常的注意事项:
编译时异常需要编译阶段处理,运行时异常编译阶段不需要管它
如果父类的方法抛出了多个异常,子类覆盖父类方法时,只能抛出相同的异常或者是他的子集
如果父类的方法没有抛出异常,子类也必须不能抛出异常
当多异常处理时,捕获处理,前边的类不能是后边类的父类
不要在finally里边写return
finally可写可不写,通常有资源需要释放时,写finally保证资源正常释放。
三.自定义异常
1.为什么要定义异常
JDK中指定义一些常用的异常类,实际开发中很可能某些异常是JDK考虑不带
所有我们需要自己定义一些异常类
2.自定义异常的步骤
a.创建一个异常类,但是异常类必须以eaception结尾
b.该异常类必须继承Exception 或者 RuntimeException
c.自定义的异常类必须是包含里两个构造(无参+String异常信息)
3.自定义异常的练习(代码演示)
要求:
我们模拟注册操作,如果用户名已存在,则抛出异常并提示:亲,该用户名已经被注册。
/** * 自定义的异常类 */ //1.必须以Exception结尾 public class MyException extends RuntimeException{ //2.至少有有两个构造 //无参构造 public MyException(){} //带有String参数的构造 public MyException(String info){ super(info); } }
测试:
public static void main(String[] args) { //注册 Scanner scanner = new Scanner(System.in); System.out.println("请输入您要注册的用户名"); String next = scanner.next(); //调用方法注册 try { register(next); System.out.println("恭喜您注册成功"); }catch (MyException e){ e.printStackTrace(); } } //注册方法 public static void register(String username) throws MyException{ //判断用户名是否重复 //1.定义一个集合,模拟数据库 ArrayList<String> usernames=new ArrayList<String>(); //添加几个已经存在的用户 Collections.addAll(usernames,"jake","bill","rose"); //2.判断用户名是否重复 if (usernames.contains(username)) { //如果用户名已经存在 throw new MyException("亲,该用户名已经被注册"); } }
四.多线程
1.并行和并发:
并行:指的两个事件同同一时刻进行
并发:指的是两个时间同一时间段内进行
宏观:我们人看到的
微观:具体的时间片段
2.进程和线程:
进程:正在运行的程序,就称为进程
线程:进程中的某一个任务,就称为线程
进程和线程的一些区别(了解)
进程是拥有(堆空间和栈空间)独立的空间(不同的之间是不能相互访问数据的),每个进程至少有一个线程
线程是在进程中执行的某个任务,可以访问进行的共享数据。一个进程各种多个线程共享堆空间,栈空间是独立的,线程消耗的资源比进程小的多。
线程调度:
就是指CPU快速地在多个线程间进行切换
CPU是单核的:那么这个CPU的某个时刻只能运行一个线程。
因为CPU可以快速地在多个线程间,进行快速切换。
CPU的两种调度:
分时调度:
按照时间片,多个线程轮流拥有CPU的执行权
抢占式调度:
CPU在多个线程之间进行随机分配(跟线程的优先级有关)
java中使用抢占式调度,所有Java中多个线程的运行也是随机的
3.创建新的线程方式***********
当我们运行java程序时,java程序就变成java进程
其中至少有两条线程,一个main线程,一条JC(java的垃圾回收器)线程
创建新的线程的方式一:
描述:一个是将一个类声明为一个Thread的子类
这个子类应该重写run类的方法,然后可以分配并启动子类的实例
步骤:
创建子类 extends Thread
重写Thread类中的run方法(就是线程“main”方法,写的就是子线程的任务代码)
创建子类的对象(在main里边写)
启动子线程 子类.start()
代码:
子线程:
public class Childthread extends Thread{ @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println("子线程"); } } }
主线程:
public static void main(String[] args) { Childthread childthread = new Childthread(); //childthread.run(); 当使用run时,就是普通方法的调用,先执行完再往下执行。 childthread.start(); for (int i = 0; i < 50; i++) { System.out.println("主线程iiiiiiiii"); } }
注:
堆空间是有垃圾回收器
标签:提示 子集 父类 index row xtend objects 集合 null
原文地址:https://www.cnblogs.com/linlin1211/p/10295952.html