异常
异常概念
异常,就是不正常的意思。在生活中:医生说,你的身体某个部位有异常,该部位和正常相比有点不同,该部位的功能将受影响.在程序中的意思就是:
- 异常 :指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止。
在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出了一个异常对象。Java处理异常的方式是中断处理。
异常指的并不是语法错误,语法错了,编译不通过,不会产生字节码文件,根本不能运行.
异常体系
Throwable体系
-
Error:严重错误Error,无法通过处理的错误,只能事先避免,好比绝症。
-
Exception:表示异常,异常产生后程序员可以处理。
1. 编译时期异常:checked异常。在编译时期会检查。没有则编译失败。
2. 运行时期异常:runtime异常,在运行时期检查异常。不必捕获。
异常处理
- throw
throw抛出一个指定的异常对象,可以是自定义的异常对象。用在方法内,用来抛出一个异常对象,将这个异常对象传递到调用者处,并结束当前方法的执行。
- throws
声明异常:将问题标识出来,报告给调用者。如果方法内通过throw抛出了编译时异常,而没有捕获处理(稍后讲解该方式),那么必须通过throws进行声明,让调用者去处理。
声明异常格式:
修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2…{ }
- try…catch捕获异常
try{
编写可能会出现异常的代码
}catch(异常类型 e){
处理异常的代码
//记录日志/打印异常信息/继续抛出异常
}finally{
一定会执行的代码
//用来释放资源(IO流,数据库连接,其他资源)
}
自定义异常
异常类如何定义:
- 自定义一个编译期异常: 自定义类 并继承于
java.lang.Exception
。 - 自定义一个运行时期的异常类:自定义类 并继承于
java.lang.RuntimeException
。
在开发中根据自己业务的异常情况来定义异常类.
自定义一个业务逻辑异常: LoginException。一个登陆异常类。
public class LoginException extends Exception{
/**
* 空参构造
*/
public LoginException(){
}
/**
* 有参构造
*/
public LoginException(String msg){
super(msg);
}
}
//-----------------------测试类-----------------------------
public class Test03 {
public static void main(String[] args) {
try {
login("admin1", "admin");
login("admin", "admin1");
login("admin", "admin");
} catch (LoginException e) {
e.printStackTrace();
}
}
private static void login(String username, String password) throws LoginException {
if(!Objects.equals(username,"admin")) throw new LoginException("用户名错误");
if(!Objects.equals(password,"admin")) throw new LoginException("密码错误");
System.out.println("欢迎" + username);
}
}
结果:...用户名错误 ....
...密码错误 ....
欢迎admin
常见的异常类
RuntimeException
Person p=null;
p.setName("张三");
System.out.println(p.getName());
//NullPointException
10 / 0
//ArithmeticException
Person p = (Person)12;
//ClassCastException
Integer.parseInt("123a");
//NumberFormatException
int a = [11,22,33];
int b = a[5];
//ArrayOutOfBoundsException
int a = "123";
a.charAt(4);
//StringIndexOutOfBoundsException
ObjectOutputStream oos = new ObjectOutputStream(inputStream);
Person p = new Person(); //没有实现Serializable接口
oos.writeObject(p)
//NoSerializableException
每个序列化的类都会根据类中的成员变量生成SerializableID。如果对成员变量进行改动,SerializableID也会发生变化。用ObjectOutputStream进行读取改动后的序列化类就会发生invalidClassException
//invalidClassException
受检查异常(会继续补充)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.parse("aaa");
//ParseException
SimpleDateFormat sdf = new SimpleDateFormat("");
//DateFormatException
Class.forName("com.zmysna.Person");
//ClassNotFoundException
FileInputStream fis = new FileInputStream("文件路径");
//FileNotFoundException
//IOException
Constructor getDeclaredConstructor(Class... parameterTypes)
Field getField(String name);
//如果不存在对应的构造方法,则会出java.lang.NoSuchMethodException 异常。
//如果不存在对应的字段,则会出java.lang.NoSuchFieldException.
Constructor[] constructors = Integer.class.getDeclaredConstructors();
for(Constructor cons : constructors) {
Integer i = cons.getInstance();
System.out.println(i);
}
//直接使用私有的构造器会产生IllegalAccessException