什么是异常?
异常就是指在程序运行的过程中发生一些不正常的时间(除0溢出,数组下标越界,所要读取的文件不存在)
java的异常是Throwable派生类的一个实例。Throwable类包含在java.lang中
Error类
LinkageError 一个类对另一个类有某种依赖关系,前者编译后,后者做了不想容的修改
VirtualMachineError java虚拟机被中断或者没有必需的资源可用
AWTError GUI实时系统的严重错误
AssertionError 一个断言失败
Execption类
ClassNotFoundException 企图使用一个不存在的类
CloneNotSupportedExecption 企图克隆一个对象
IOException 与输入/输出相关的操作
AWTExecption GUI组件异常
RuntimeException类
ArithmeticException 一个整数除以0
NullPointException 企图通过null引用变量访问一个对象
IndexOutofBoundsException 数组的下标超出范围
IllegalArgumentException 将一个无效或不合适的参数传递个方法
RuntimeException、error以及它们的子类都称为免检异常。所有其他的异常都称为必检异常,意思是编译器会强制程序员来处理它们,大多数情况下,免检异常反映程序设计中不可重获的逻辑错误。这些都是程序中必须纠正的错误,免检异常可能在程序的任何地方出现,避免过多的使用try-catch块,java语言不允许编写捕获或声明免检异常的代码。
java的异常是通过两种机制来处理的
捕获:try-catch-finally
抛出:throw,throws
try:监控区域,执行可能产生异常的代码
catch:捕获、处理异常
finally:善后处理,无论是否发生异常,代码总能执行
throw:手动抛出异常
throws:声明方法可能要抛出的异常,抛出的异常交由调用者处理
子类的catch块一定要在父类的catch块前面
Java异常处理模型:声明异常、抛出异常和捕获异常
method1(){
try{
invoke method2;
}
catch(Exception ex){ //捕获异常
Process exception;
}
}
method2() throws Exception{ /// 声明异常
if(an error occurs){
throw new Exception; //抛出异常
}
}
import java.util.*;
public class helloworld{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
try{
int number = sc.nextInt();
System.out.println(number);
}
catch(Exception ex){
System.out.println("Try again");
sc.nextLine();
}
}
}
// 输入浮点数就会异常
try{
Statements;
}
catch(Exception1 e1){ //不同异常类型
handler for Exception1;
}
catch(Exception e2){
handler for Exception2;
}
....
如果执行try块的过程中没有出现异常,则跳过catch语句
如果异常不能在当前的方法中捕获,就传给该方法的调用者,这个过程一直重复,直到异常被捕获或被传给main方法
处理异常方法
toString: 返回异常信息
getMessage : 返回throwable的详细信息字符串
printStackTrace:将此throwable及其追踪输出至标准错误流
package my;
import java.util.*;
public class HelloWorld {
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
try {
int number = sc.nextInt();
System.out.println(number);
}
catch(Exception ex){
System.out.println(ex.getMessage());
ex.printStackTrace();
}
}
}
finally子句
不论异常是否出现或者被捕获,都希望执行的某些代码
可以释放资源,比如关闭打开的文件,删除一些临时文件等
除了在之前执行了System.exit(0)
try可以直接和finally一起使用
try{
statements;
}
catch(Exception e){
handing e;
}
finally{
finalStatements;
}
throw和throws的区别
throw用在方法内,后面跟上要抛出的异常类对象
throws修饰在方法上,告诉调用者此方法可能会抛出异常,后面跟上可能要抛出的异常类名
package my;
import java.util.*;
public class HelloWorld {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int age = sc.nextInt();
try {
bar.enter(15);
}
catch(Exception e) {
System.out.println("wrong message: " + e.getMessage());
}
System.out.println("end");
}
}
class bar{
public static void enter(int age)throws Exception{
//throws 提醒此方法可能有异常
if(age < 18) {
throw new Exception("to small");
//向外抛出异常
}
else {
System.out.println("Welcome");
}
}
}
自定义异常
自定义异常类必须从已有的异常类继承(一般继承Exception)
对于异常来说,最重要的部分就是它的类名
可以为异常类定义一个接受字符串参数的构造方法,字符串参数描述异常信息
package my;
import java.util.*;
public class HelloWorld {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int age = sc.nextInt();
try {
bar.enter(age);
}
catch(AgeLessThanEighteenException e) {
System.out.println("wrong message: " + e.getMessage());
}
System.out.println("end");
}
}
//自定义异常类
class AgeLessThanEighteenException extends Exception{
private String message;
public AgeLessThanEighteenException(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
class bar{
public static void enter(int age)throws AgeLessThanEighteenException{
if(age < 18) {
throw new AgeLessThanEighteenException("to small");
}
else {
System.out.println("Welcome");
}
}
}
eg:
30
Welcome
end
eg:
15
wrong message: to small
end
eg:医生给工作者看病
package my;
import java.util.Random; //随机数的包
public class Test {
public static void main(String[] args) {
worker w = new worker();
doctor d = new doctor();
try{
w.work();
}
catch(SickException e) { //捕获异常
doctor.cure(w);
if(w.getStatus().equals("health")) {
System.out.println("health,Congulation");
}
else {
System.out.println("Sorry");
}
}
finally{ //总是要执行的语句
System.out.println("Welcome to hosptial next time");
}
}
}
class worker{ //work的类
private String status;
public void setStatus(String status) { //设置status的值
this.status = status;
}
public String getStatus() { //得到status的值
return status;
}
public static void work() throws SickException { //work方法可能回抛出异常
Random r = new Random();
int rad = r.nextInt(2) + 1;
if(rad == 1) {
System.out.println(rad + ": I have ill");
throw new SickException("I have ill");
}
else {
System.out.println(rad + ": body well");
}
}
}
class SickException extends Exception{ //定义异常类
private String message;
public SickException(String massage) {
this.message = message;
}
public String getMessage() {
return message;
}
}
class doctor{ //doctor的类
public static void cure(worker w) {
Random r = new Random();
int rad = r.nextInt(2) + 1;
if(rad == 1) {
w.setStatus("health");
}
else {
w.setStatus("die");
}
}
}
eg:
1: I have ill
health,Congulation
Welcome to hosptial next time
断言
断言是java的一种语句,它允许对程序提出一个判断(假设)。断言包含一个布尔表达式,在程序运行中它应该是真。断言用于确保程序的正确性,避免逻辑错误
声明断言:assert
assert assertion;
assert assertion : detailMessage;
其中assertion是一个布尔表达式,detailMessage是一个基本类型或者一个对象值
执行断言语句时,java计算断言assertion的值,如果是false,抛出AssertionError异常。该类有一个无参构造方法和七个重载的单参数构造方法,参数类型为int,long,float,double,boolean,char和Object。
package my;
import java.util.*;
public class HelloWorld {
public static void main(String[] args){
int i;
int sum = 0;
for(i = 0; i < 10; ++i) { // i < 100 时会抛出异常
sum += i; // sum += 1 时会抛出异常
}
assert i == 10;
assert sum > 10 && sum < 5 * 10:"sun is" + sum;
}
}
不应该使用断言代替异常处理,异常处理用于在程序运行期间处理非常环境,断言是要确保程序的正确性。异常处理针对程序的健壮性,而断言设计程序的正确性。与异常处理类似,断言不能代替正常的检验,只是检测内部的一致性和有效性。断言在运行是检验,可以在程序启动时打开或关闭。
不要使用断言检测public方法的参数。传给public方法的有效参数被认为是方法合约的一部分。无论断言是否起作用,都必须遵守合约。
elicpse如何运行带断言的程序