异常和错误
- 程序错误
- 错误是必须要修改代码才可以修复的
- 必须要将相关的代码进行修改,避免错误的出现
异常
定义一份可能出现异常的代码
int money = scanner.nextInt();
money = money /10;
System.out.println(money);
使用try…catch捕获异常,并且进行相关的处理
Scanner scanner = new Scanner(System.in);
try{
int money = scanner.nextInt();
money = money /10;
System.out.println(money);
}catch(Exception e){
System.out.println("请输入正确的数字");
//自带的打印异常信息的方法
// e.printStackTrace();
//System.out.println(e.getMessage());
}
编程中常见异常
Exception是所有的异常的父类,在其基础上根据异常不同,其子类继承之后拥有不同的类型
常见异常
NullPointerException:空指针异常
try {
Student s = null;
s.setName("小明");
}catch (NullPointerException e){
System.out.println("输入的用户不可以为空");
}
ArrayIndexOutOfBoundsException:数组越界异常
Integer[] arrs = new Integer[10];
int index = 85;
try{
arrs[index] = 0;
}catch (ArrayIndexOutOfBoundsException e){
System.out.println("数组越界异常");
}
ClassCastException: 类型转换异常
Object s = new Student("小明",15);
try {
Person p = (Person) s;
}catch (ClassCastException e){
System.out.println("学生不可以转换成person类");
}
其他异常
//4NumberFormatException格式异常
try {
int n=Integer.parseInt("100a");
System.out.println(n);
}catch (NumberFormatException e){
e.printStackTrace();
}
//5ArithmeticExceptioin算术异常
int m=10/0;
System.out.println(m);
异常的创建与抛出
可以手动抛出异常(但是抛出异常必须要被处理)
String input = scanner.next();
if(input.equals("脏话")){
//抛出异常,必须要被处理
throw new Exception();
}
抛出的异常有两种处理方式
方式1:直接进行处理(毫无意义)
try {
throw new Exception();
} catch (Exception e){
System.out.println("不许说脏话");
}
方式2:将异常通过方法抛出去,在调用这个方法的时候处理异常
//获取输入值
public static String getInput() throws Exception {
Scanner scanner = new Scanner(System.in);
String input = scanner.next();
if(input.equals("脏话")) {
//抛出异常,必须要被处理
throw new Exception();//相当于return
//程序已经结束来了
}
return input;
}
public static void main(String[] args) {
System.out.println("请输入聊天记录");
try {
String result = getInput();
}catch (Exception e){
System.out.println("不准输入脏话");
}
}
自定义不同类型的异常
创建一个类继承异常
- 然后在其他代码中直接new出一个自定义的异常
登录案例
创建没有用户名的异常
public class UsernameNotExistException extends Exception{
}
创建密码不存在异常
public class PasswordFailException extends Exception {
}
在代码中抛出异常,并且分开进行处理
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String username;
String password;
System.out.println("请输入用户名");
username = scanner.next();
System.out.println("请输入密码");
password = scanner.next();
try {
login(username,password);
//如果login抛出了异常try中之后的代码是不会再允许的
//如果没有异常那么登录成功
System.out.println("登录成功");
}catch (UsernameNotExistException e){//用户名称错误异常
System.out.println("用户不存在");
}catch(PasswordFailException e){//密码错误异常
System.out.println("密码错误");
}
}
//登录方法
public static void login(String username,String pwd)
throws UsernameNotExistException, PasswordFailException {
if(!username.equals("张三")){
throw new UsernameNotExistException();
}
if(!pwd.equals("123")){
throw new PasswordFailException();
}
}
重写异常的相关方法,提高异常的功能
创建一个类继承exception,添加消息数据,重写获取消息方法
public class LoginFailException extends Exception{
String msg;//用于存储异常的说明
//重载构造方法
public LoginFailException(String msg) {
this.msg = msg;
}
//重写getMessage方法
@Override
public String getMessage() {
return this.msg;
}
}
调用异常
//实现登录方法
public static void login(String username,String pwd)
throws LoginFailException {
//判断账号是否正确
if(!username.equals("张三")){
//抛出账号错误异常
throw new LoginFailException("用户不存在");
}
//判断密码是否正确
if(!pwd.equals("123")){
//抛出密码错误的异常
throw new LoginFailException("密码错误");
}
}
public static void main(String[] args) {
//输出信息的代码
Scanner scanner = new Scanner(System.in);
String username;
String password;
while(true){
System.out.println("请输入用户名");
username = scanner.next();
System.out.println("请输入密码");
password = scanner.next();
//登录代码
try {
login(username,password);
System.out.println("登录成功");
break;
} catch (LoginFailException e) {
System.out.println(e.getMessage());
}
}
System.out.println("程序结束");
}
检查异常和非检查异常
检查异常:异常必须要被处理
- 继承了是Exception
- 一些程序比如文件操作,网络操作,线程等等,可能是由于硬件的缘故爆出的异常都应该被强制检查
- 非检查异常:可以不用强制处理
- 继承的是RuntimeException
- 有一些程序,出现的异常是由于用户输入的错误,计算的错误等等,可以通过相关代码进行规避的异常,可以不被强制执行
一般情况下,自定义的异常都是选择继承RuntimeException
异常处理的关键字
try: 包裹可能会出现异常的代码,
- 如果在try中某一行代码抛出了异常,会直接进入到对应异常的catch代码中,try中的程序都中止了。
- 但是try外部的程序还是可以继续运行
catch:是处理异常的代码
- 会将抛出的异常传递到catch的代码快中
- catch可以接收多个异常处理的
- 如果catch是多个异常的父类,那么在抛出多个不同异常的时候,会直接进入到这个catch父类的代码中
try{
login(username,password);
//如果login抛出了异常try中之后的代码是不会再允许的
//如果没有异常那么登录成功
System.out.println("登录成功");
}catch (Exception e){
if( e instanceof UsernameNotExistException){
System.out.println("用户不存在");
}else if(e instanceof PasswordFailException){
System.out.println("密码不正确");
}
}
finally: 其中的代码无论是否出现异常都被执行
try…catch…finally的使用
try {
login(username,password);
System.out.println("登录成功");
break;
} catch (LoginFailException e) {
System.out.println(e.getMessage());
} finally {
System.out.println("本次输入结束");
}
try…finally
try{
System.out.println("执行的相关");
int i=1/0;
}finally {
System.out.println("程序中止了");
}