版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_37860140/article/details/93871370
【Java】异常处理
java中的异常
1.异常简介
Java 中的异常(Exception)又称为例外,是一个在程序执行期间发生的事件,它中断正在执行的程序的正常指令流。为了能够及时有效地处理程序中的运行错误,必须使用异常类。
2.异常产生的原因
Java 内部错误发生异常,Java 虚拟机产生的异常。
编写的程序代码中的错误所产生的异常,例如空指针异常、数组越界异常等。这种异常称为未检査的异常,一般需要在某些类中集中处理这些异常。
通过 throw 语句手动生成的异常,这种异常称为检査的异常,一般用来告知该方法的调用者一些必要的信息。
3.使用原则
在当前方法声明中使用 try catch 语句捕获异常。
一个方法被覆盖时,覆盖它的方法必须拋出相同的异常或异常的子类。
如果父类抛出多个异常,则覆盖方法必须拋出那些异常的一个子集,而不能拋出新异常。
4.异常的类型分类
Throwable 类是所有异常和错误的超类,下面有 Error 和 Exception 两个子类分别表示错误和异常。其中异常类 Exception 又分为运行时异常和非运行时异常,这两种异常有很大的区别,也称为未检查异常(Unchecked Exception)和检查异常(Checked Exception)。
运行时异常(未检查异常)
如 NullPointerException、IndexOutOfBoundsException 等,程序中可以选择捕获处理,也可以不处理。这些异常一般由程序逻辑错误引起,程序应该从逻辑角度尽可能避免这类异常的发生。
非运行时异常(检查异常)
必须进行处理的异常,如果不处理,程序就不能编译通过。如 IOException、ClassNotFoundException 等以及用户自定义的 Exception 异常。
Java异常处理机制
Java 的异常处理通过 5 个关键字来实现:try、catch、throw、throws 和 finally。
try catch 语句用于捕获并处理异常
finally 语句用于在任何情况下(除特殊情况外)都必须执行的代码
throw 语句用于拋出异常
throws 语句用于声明可能会出现的异常
Java 的异常处理机制提供了一种结构性和控制性的方式来处理程序执行期间发生的事件。异常处理的机制如下:
在方法中用 try catch 语句捕获并处理异常,catch 语句可以有多个,用来匹配多个异常。
对于处理不了的异常或者要转型的异常,在方法的声明处通过 throws 语句拋出异常,即由上层的调用方法来处理。
try
{
逻辑程序块
}
catch(ExceptionType1 e)
{
处理代码块1
}
catch (ExceptionType2 e)
{
处理代码块2
throw(e); //再抛出这个"异常"
}
finally
{
释放资源代码块
}
Java Try Catch语句
try
{
逻辑代码块1;
}
catch(ExceptionType e)
{
处理代码块1;
}
如
3ff7
果 try 语句块中发生异常,那么一个相应的异常对象就会被拋出,然后 catch 语句就会依据所拋出异常对象的类型进行捕获,并处理。处理之后,程序会跳过 try 语句块中剩余的语句,转到 catch 语句块后面的第一条语句开始执行。
如果 try 语句块中没有异常发生,那么 try 块正常结束,后面的 catch 语句块被跳过,程序将从 catch 语句块后的第一条语句开始执行。
3 个方法输出相应的异常信息。
printStackTrace() 方法:指出异常的类型、性质、栈层次及出现在程序中的位置。
getMessage() 方法:输出错误的性质。
toString() 方法:给出异常的类型与性质。
Java Try Catch Finally语句
根据 try catch 语句的执行过程,try 语句块和 catch 语句块有可能不被完全执行,而有些处理代码则要求必须执行,例如文件的关闭、释放资源等,此时就可以将这些代码放在 finally 语句块中。
try
{
逻辑代码块
}
catch(ExceptionType e)
{
异常处理代码块
}
finally
{
清理代码块
}
Java声明和抛出异常
1.throws声明异常
当一个方法产生一个它不处理的异常时,那么就需要在该方法的头部声明这个异常,以便将该异常传递到方法的外部进行处理。使用throws关键字声明异常,如果有多个异常类,它们之间用逗号分隔。
import java.io.FileInputStream;
import java.io.IOException;
public class Test
{
public void readFile() throws IOException
{
//定义方法时声明异常
FileInputStream file=new FileInputStream("read.txt"); //创達 FileInputStream 实例对象
int f;
while((f=file.read())!=-1)
{
System.out.println((char)f);
f=file.read();
}
file.close();
}
public static void main(String[] args)
{
Throws t=new Test();
try
{
t.readFile(); //调用 readFHe()方法
}
catch(IOException e)
{ //捕获异常
System.out.println(e);
}
}
}
2.throw抛出异常
throw 语句用来直接拋出一个异常,后接一个可拋出的异常类对象.
当 throw 语句执行时,它后面的语句将不执行,此时程序转向调用者程序,寻找与之相匹配的 catch 语句,执行相应的异常处理程序。
Java 自定义异常
如果 Java 提供的内置异常类型不能满足程序设计的需求,可以设计自己的异常类型。自定义异常类必须继承现有的 Exception 类或 Exception 的子类来创建。
自定义异常类一般包含两个构造方法:一个是无参的默认构造方法,另一个构造方法以字符串的形式接收一个定制的异常消息,并将该消息传递给超类的构造方法。
异常处理实例
1.录入学生姓名、年龄和性别,要求能捕捉年龄不为数字时的异常
import java.util.Scanner;
public class Test
{
public static void main(String[] args)
{
Scanner scanner=new Scanner(System.in);
System.out.println("---------学生信息录入---------------");
String name=""; //获取学生姓名
int age=0; //获取学生年龄
String sex=""; //获取学生性别
try
{
System.out.println("请输入学生姓名:");
name=scanner.next();
System.out.println("请输入学生年龄:");
age=scanner.nextInt();
System.out.println("请输入学生性别:");
sex=scanner.next();
}
catch(Exception e)
{
e.printStackTrace();
System.out.println("输入有误!");
}
System.out.println("姓名:"+name);
System.out.println("年龄:"+age);
}
}
2.计算平均成绩,要求能捕捉异常
import Java.util.InputMismatchException;
import java.utii.Scanner;
public class Test
{
public static void main(String[] args)
{
Scanner input=new Scanner(System.in);
try
{
System.out.println("请输入班级总人数:");
int count=input.nextInt();
System.out.println("请输入总成绩:");
int score=input.nextInt();
int avg=score/count; //获取平均分
System.out.pr
8000
intln("本次考试的平均分为:"+avg);
}
catch(InputMismatchException e1)
{
System.out.println("输入数值有误!");
}
catch(ArithmeticException e2)
{
System.out.println("输入的总人数不能为0!");
}
catch(Exception e3)
{
e3.printStackTrace();
System.out.println("发生错误!"+e3.getMessage());
}
}
}
3.验证用户信息
public class LoginException extends Exception
{
public LoginException()
{
super();
}
public LoginException(String msg)
{
super(msg);
}
}
public class Test{
public boolean validateLogin(String username,String pwd)
{
boolean con=false; //用户名和密码是否正确
boolean conUname=false; //用户名格式是否正确
try
{
if(username.length()>=6&&username.length()<=10)
{
for(int i=0;i
{
char ch=username.charAt(i); //获取每一个字符
if(ch>='0'&&ch<='9')
{ //判断字符是否为0~9的数字
conUname=true; //设置 conUname 变量值为 true
}
else
{ //如果字符不是0~9的数字,则拋出LoginException异常
conUname=false;
throw new LoginException("用户名中包含有非数字的字符!");
}
}
}
else
{ //如果用户名长度不在6~10位之间,拋出异常
throw new LoginException("用户名长度必须在6〜10位之间!");
}
if(conUname==true)
{ //如果用户名格式正确,判断密码长度
if(pwd.length()==6)
{ //如果密码长度等于6
con=true; //设置con变量的值为true,表示登录信息符合要求
}
else
{ //如果密码长度不等于6,拋出异常
con=false;
throw new LoginException("密码长度必须为 6 位!");
}
}
}
catch(LoginException e)
{ //捕获 LoginException 异常
System.out.println(e.getMessage());
}
return con;
}
public static void main(String[] args)
{
Scanner input=new Scanner(System.in);
System.out.println("用户名:");
String username=input.next();
System.out.println("密码:");
String password=input.next();
Test t=new Test ();
boolean con=t.validateLogin(username,password); //调用 validateLoginO 方法
if(con)
{
System.out.println("登录成功!");
}
}
}