1.1 异常概念
异常是Java中提供的一种识别及响应错误情况的一致性机制。有效地异常处理能使程序更加健壮、易于调试。
异常发生的原因有很多,比如:
1 用户输入了非法数据
2 要打开的文件不存在
3 网络通信是链接中断
4 JVM内存溢出
5 异常发生的原因有很多,尤其是用户输入和要打开的资源不存在
这些异常出错后,导致程序生命周期终止执行,从错误代码开始,之后的代码都不会执行
如:
public class Exception_01 {
public static void main(String[] args) {
System.out.println(1);
System.out.println(2);
String s = null;
s.equals("");
System.out.println(3);
System.out.println(4);
// 结果为: 1
// 2
// Exception in thread "main" java.lang.NullPointerException
// at com.Exception_01.main(Exception_01.java:18)
// 异常后面的代码不再执行
}
}
之前常见异常有:空指针 ,下标越界,栈内存溢出,类型转换异常
1.2 异常继承体系
1.3 error
1.3.1 概念
系统内部错误,这类错误由系统进行处理,程序本身无需捕获处理。
比如:OOM(内存溢出错误)、VirtualMachineError(虚拟机错误)、StackOverflowError(堆栈溢出错误)等,一般发生这种情况,JVM会选择终止程序。
2. 示例:
//堆栈溢出错误
public class TestError {
public static void recursionMethod() {
recursionMethod();// 无限递归下去
}
public static void main(String[] args) {
recursionMethod();
}
}
报错信息:
Exception in thread "main" java.lang.StackOverflowError
at com.TestError.recursionMethod(TestError.java:5)
at com.TestError.recursionMethod(TestError.java:5)
at com.TestError.recursionMethod(TestError.java:5)
at com.TestError.recursionMethod(TestError.java:5)
at com.TestError.recursionMethod(TestError.java:5)
at com.TestError.recursionMethod(TestError.java:5)
... ...
1.4 exception
1.4.1 概念
Exception是所有异常类的父类。分为非RuntimeException和RuntimeException 。
- 非RuntimeException
指程序编译时需要捕获或处理的异常,如IOException、自定义异常等。属于checked异常。
RuntimeException
指程序编译时不需要捕获或处理的异常,如:NullPointerException等。属于unchecked,异常。一般是由程序员粗心导致的。如空指针异常、数组越界、类型转换异常等。
1.4.2 常用方法
1.4.3 异常处理方式
1 throws : 抛出异常,告诉调用处,这里可能有什么问题
如果你把异常抛给了调用处.那么调用处要么也抛出去,要么解决
2 try...catch... : 解决异常
try{
高风险代码;
}catch(异常类型 变量){
解决方案;
}
throws 抛出异常,并不会处理异常,是一种提醒机制
如果你调用 的方法,抛出一个编译时异常,要么你就try..catch处理掉,要么你也抛出
throws 是抛出异常,并不会解决异常,一般用于类库端(被调用的这个类)
而 try...catch... 是解决异常的,一般用于客户端(调用其他类的这个类,一般客户端都有main方法)
例子:
public class Exception_02 {
public static void main(String[] args) {
}
public static void m1() throws FileNotFoundException{
FileInputStream fileInputStream=new FileInputStream("D:\\xxx.txt");//打开文件资源
}
public static void m2(){
try {
FileInputStream fileInputStream=new FileInputStream("D:\\xxx.txt");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
1.4.4 try{} catch{} catch{}....
try{
高风险代码;
} catch(异常类型 变量){
处理方案;
} catch(异常类型 变量){
处理方案;
}...
catch中异常类型 不能有继承关系,如果有继承关系,需要从子类到父类,也就是说上面的catch范围要比下面的catch小,或者平级
例子:
public class Exception_05 {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
FileInputStream fis = new FileInputStream("");
} catch (FileNotFoundException e) {
System.out.println("找不到文件");
} catch (NullPointerException e) {
System.out.println("不能为null");
} catch (Exception e) {
System.out.println("其他异常");
}
}
}
抛异常 可以同时抛出多个,逗号隔开,没有先后顺序
例子:
package com;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Exception_06 {
// 抛异常 可以同时抛出多个,逗号隔开,没有先后顺序
public static void main(String[] args) throws Exception,
FileNotFoundException, IOException {
}
}
1.5 finally
1.5.1 概念
finally : 必须执行的语句块 比如 打开的资源,需要关闭
1.5.2 用法
1 finally 不能单独出现,必须和try一起使用 或者和 try...catch...一起使用
2 finally语句块 只有一种不执行的情况,那就是关闭虚拟机 System.exit(0);
例子:
public class Exception_07 {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
int a = 0;
int b = 3;
// 除数不能为0,会出错
int c = b / a;
System.out.println(c);
} catch (Exception e) {
e.printStackTrace();
// 终止方法执行
return;
// System.exit(0);
} finally {
// 但是finally会执行
System.out.println("2222");
}
// 执行不到,因为上面有return
System.out.println("1111");
}
1.6 资源关闭
Java1.7新特性 自动关闭资源
手动关闭(finally)
try{
开启资源;
}catch(异常类型 变量){
处理措施;
}finally{
关闭资源
}
-----
自动关闭:
try(开启资源){
高风险代码;
}catch(异常类型 变量){
处理措施;
}
手动关闭资源(finally)
public class Exception_09 {
public static void main(String[] args) {
// TODO Auto-generated method stub
FileInputStream file=null;
try {
file=new FileInputStream("");
} catch (Exception e) {
// TODO: handle exception
}finally{
//关闭资源
try {
if(file!=null)
file.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
自动关闭
public class Exception_10 {
public static void main(String[] args) {
//自动关闭资源
try(FileInputStream file=new FileInputStream("");){
// 操作
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
1.7 自定义异常
用法:
1 继承一个已有的异常类
判断你应该是运行是异常还是编译时异常,如果是运行时异常需要继承 RuntimeException 否则就继承Exception即可
一般情况下 我们写的 一定是 编译时异常
2 公共的无参构造
3 公共的有参构造,传入字符串,并在构造方法中把该字符串传递给父类
public class UserException extends Exception {
public UserException(){
}
public UserException(String mag){
super(mag);
}
}
1.8 用户登录之自定义异常例子
需求 完成用户登陆
1 如果用户名不是admin 则提示用户名不存在 2 如果密码不是root 则提示密码不正确
客户端负责数据录入
1 Client(客户端类)
public class Client {
public static void main(String[] args) {
Scanner sr=new Scanner(System.in);
System.out.println("请输入用户名:");
String username=sr.next();
System.out.println("请输入密码:");
String password=sr.next();
// System.out.println(username+":"+password);
UserServer user=new UserServer();
try {
String result=user.Login(username, password);
if(result.equals("登录成功")){
System.out.println("欢迎回来!!!");
}
} catch (UserException e) {
e.printStackTrace();
// System.out.println(e.getMessage());
}
}
}
2 UserException(自定义异常类)
public class UserException extends Exception {
public UserException(){
}
public UserException(String mag){
super(mag);
}
}
3 UserServer
service 负责 逻辑校验
public class UserServer {
public static String Login(String username,String password) throws UserException{
if(username.equals("admin")){
if(password.equals("root")){
return "登录成功";
}else {
throw new UserException("密码错误!!!");
}
}else {
throw new UserException("用户名不存在!!!");
}
}
}