/*
java 中的所有异常类都是继承自 Throwable类,就是说所有的异常类都是
Throwable类的子类.
所有的类都是 Object 类的子类,Throwable类有两个子类,Error类和Exception类,
主要关注的就是 Exception类,
其中 Exception 类包括 RuntimeException和其他异常类
*/
public class Hi
{
public static void exception()
{
int i[] = {1,2,3};
System.out.println("i[3] = "+i[3]);
}
public static void main(String[] args)
{
exception(); // 数组越界异常,报错
}
}
// 常见的运行时异常类(RuntimeException)
java.lang.ArithmeticException: 算术异常
java.lang.ArrayIndexOutOfBoundsException:数组越界异常
java.lang.ArrayStoreException:数组元素值类型与数组类型不符异常
java.lang.ClassCastException:对象转换异常
java.lang.IllegalArgumentException:调用方法时传入非法参数异常
java.lang.IllegalMonitorStateException:非法监控操作异常
java.lang.IllegalStateException:java环境或java应用程序状态异常
java.lang.IllegalThreadStateException:线程没有处于请求操作所要求状态异常
java.lang.IndexOutOfBoundsException:索引越界异常
java.lang.NegativeArraySizeException:数组长度为负值异常
java.lang.NullPointerException:空指向异常
java.lang.NumberFormatException:数字格式异常
java.lang.SecurityException:违反安全性异常
java.lang.StringIndexOutOfBoundsException:字符串索引越界异常
java.lang.UnsupportedOperationException:操作错误异常
检查异常
java.lang.Exception:处理异常的基本异常类
java.lang.ClassNotFoundException:找不到相关异常
java.lang.CloneNotSupportedException:使用继承自Object类的 clone()方法,但是该类没有实现 Cloneable 接口
java.lang.IllegalAccessException:访问类被拒绝异常(与权限有关)
java.lang.InstantiationException:创建抽象类或接口对象实例异常
java.lang.InterruptedException:线程被另一个线程中断异常
java.lang.NosuchFieldException:在类中找不到此字段异常
java.lang.NosuchMethodException:在类中找不到此方法异常
/*
虽然系统提供了默认的异常处理程序,但是一般情况下,还是开发人员更希望的是自己处理异常:
两种处理异常处理方法:
try ... catch ... finally ...//语句处理异常
throws 关键字将异常传递出来
*/
try
{
// 可能抛出异常的语句
}catch(异常类型1 异常对象名1)
{
// 对该类型的异常进行处理的语句
}[catch(异常类型2 异常对象名2) {} ... ]
[finally{
// 一定会运行的程序代码
}]
// ===========
public class Hi
{
public static void main(String[] args)
{
int i[] = {1,2,3};
try
{
System.out.println("i[0] = "+i[0]);
System.out.println("i[3] = "+i[3]); // 数组越界异常
}catch(ArrayIndexOutOfBoundsException e)
{
System.out.println("异常信息:"+e);
}
System.out.println("i[1] = "+i[1]); // 正常执行
}
}
/*
i[0] = 1
异常信息:java.lang.ArrayIndexOutOfBoundsException: 3
i[1] = 2
*/
// =============
public class Hi
{
public static void main(String[] args)
{
int i[] = {1,2,3};
try
{
System.out.println("i[0] = "+i[0]);
System.out.println("i[3] = "+i[3]); // 数组越界
}catch(ArrayIndexOutOfBoundsException e)
{
System.out.println("异常信息:"+e);
}finally
{
System.out.println("无论如何都执行的语句");
}
System.out.println("i[1] = "+i[1]); // 正常执行
}
}
/*
i[0] = 1
异常信息:java.lang.ArrayIndexOutOfBoundsException: 3
无论如何都执行的语句
i[1] = 2
*/
// =============
// 多个 catch语句块
import java.util.Scanner;
import java.util.InputMismatchException;
public class Hi
{
public static void main(String[] args)
{
Scanner read = new Scanner(System.in);
int arr[] = new int[5];
try
{
System.out.println("请输入数组元素:");
for(int i=0; i<arr.length; i++)
{
arr[i] = read.nextInt();
}
System.out.println("请输入数组元素索引:");
int n = read.nextInt();
System.out.println("arr["+n+"]="+arr[n]);
int m = arr[3]/arr[0];
System.out.println("m = "+m);
}catch(ArrayIndexOutOfBoundsException e) // 捕捉数组越界异常
{
System.out.println("异常:"+e);
}catch(ArithmeticException e) // 捕捉算术异常
{
System.out.println("异常:"+e);
}catch(InputMismatchException e) // 捕捉输入不匹配异常
{
System.out.println("异常:"+e);
}
System.out.println("end ... ");
}
}
// ============
throws 使用格式
[访问控制符] 返回类型 方法名称([参数列表]) throws 异常类1[, 异常类2..]{}
import java.io.IOException;
import java.io.FileInputStream;
public class Hi
{
public static void arrException() throws IOException
{
FileInputStream f = new FileInputStream("不存在的文档.txt");
}
public static void main(String[] args)
{
try
{
arrException();
}catch(Exception e)
{
System.out.println("异常:"+e);
}
}
}
// 异常:java.io.FileNotFoundException: 不存在的文档.txt (系统找不到指定的文件。)
// ==========
import java.io.IOException;
import java.io.FileInputStream;
public class Hi
{
public static void arrException() throws IOException
{
FileInputStream f = new FileInputStream("文件不存在.txt");
}
public static void main(String[] args) throws Exception
{
arrException();
}
}
/*
Exception in thread "main" java.
不到指定的文件。)
at java.io.FileInputStre
at java.io.FileInputStre
at java.io.FileInputStre
at Hi.arrException(Hi.ja
at Hi.main(Hi.java:11)
*/
主方法 main()使用了 throws 关键字,
没有使用 try .. catch 语句,所以arrException()方法
将异常抛出交给 main() 方法时,main也不作任何处理继续向上抛出,
直至抛给 JVM.JVM就会调用默认异常处理程序处理,
即中断程序的执行并退出。
// ===============
/**
throw 自行抛出异常。throw语句可以单独使用,用于方法体内部,
throw 抛出的不是异常类,而是异常类的实例。
如果抛出了检查异常,则还应该在方法头部声明方法可能抛出的异常类型,
该方法的调用者也必须检查处理抛出的异常。
不检测异常与检测异常
不检测异常是指对 Error类或其子类对象和 RuntimeException类或其子类
就不用捕获或抛出。其他的异常类就是检查异常
throw 使用格式
throw 异常对象;
*/
// 自行抛出不检查异常
import java.io.IOException;
public class Hi
{
public static void arrException() // 不需要指明可能抛出的类型
{
throw new NullPointerException("自行抛出不检查异常--空指定异常");
}
public static void main(String[] args)
{
try // 处理异常
{
arrException(); // 产生异常
}catch(Exception e) // 捕获异常
{
System.out.println(e);
}
}
}
/*
result:
java.lang.NullPointerException: 自行抛出不检查异常--空指定异常
*/
import java.io.IOException;
public class Hi
{
public static void arrException() throws Exception
{
throw new IOException("自行抛出检查异常--IO异常");
}
public static void main(String[] args)
{
try // 处理异常
{
arrException(); // 产生异常
}catch(Exception e) // 捕获异常
{
System.out.println(e);
}
}
}
// java.io.IOException: 自行抛出检查异常--IO异常
/*
以上两个程序产生的异常对象都是手工产生的。使用 throw抛出不检查异常时,
不需要在方法头部声明方法可能抛出的异常类型。
而抛出检查异常时,必须在方法头部声明可能抛出的异常类型,
该方法的调用者也必须检查处理抛出异常.
*/
// ==============
// catch和 throw同时使用
import java.util.Scanner;
public class Hi
{
public static void arrException(int arr[])
{
try
{
int m = arr[2]/arr[0];
System.out.println(arr[2]+"/"+arr[0]+"="+m);
}catch(ArithmeticException e)
{
e.printStackTrace();
/*java.lang.ArithmeticException: /
at Hi.arrException(Hi.ja
at Hi.main(Hi.java:27)
*/
throw new ArithmeticException("被除数不能为0,所以arr[0]不能为0");
}
}
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
int arr[] = new int[5];
try
{
for(int i = 0; i<arr.length; i++)
{
System.out.println("第"+(i+1)+"元素:");
arr[i] = scan.nextInt();
}
arrException(arr);
}catch(Exception e)
{
System.out.println("异常信息:"+e);
}
}
}
/*
java.lang.ArithmeticException: / by zero
at Hi.arrException(Hi.java:8)
at Hi.main(Hi.java:31)
异常信息:java.lang.ArithmeticException: 被除数不能为0,所以arr[0]不能为0
*/
/**
自定义异常类格式
[public ] class 自定义的异常类名 extends Exception类或Exception类的子类{}
*/
import java.util.Scanner;
class MyNumberException extends Exception // 自定义异常类
{
public MyNumberException(){} // 无参构造方法
public MyNumberException(String message) // 参数为 string 类型的构造方法
{
super(message);
}
}
public class Hi
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
int arr[] = new int[5];
try // 处理异常
{
for(int i = 0; i < arr.length; i++)
{
System.out.println("输入第"+(i+1)+"个数:");
arr[i] = scan.nextInt();
if(arr[i] < 0 || arr[i] > 100)
{
throw new MyNumberException("你输入的数不在 0 - 100");
}
}
}catch(MyNumberException e) // 抓取异常
{
System.out.println(e); // 输出异常信息
}catch(Exception e) // 抓取异常
{
System.out.println(e); // 输出异常信息
}
}
}
/**
当输入的数字不在 0 -100 之间时,会提示:
MyNumberException: 你输入的数不在 0 - 100
*/
// ------------
/**
断言(assertion)在程序中只是一条语句,断言可以对布尔表达式进行检查。
一旦这个表达式的值为 false,就说明该程序已经处于不正确的状态,
会提示错误信息.
断言格式:
1.
assert 布尔表达式;
2.
assert 布尔表达式:细节描述信息;
如果布尔表达式的结果为 true,则没有任何错误提示信息,
若布尔表达式为 false,则会有错误提示信息。
如果在定义断言时没有声明细节信息,
那么系统将会使用默认的错误信息提示方式
断言返回的布尔值不能作为条件判断语句
*/
public class Hi
{
public static void main(String[] args)
{
int score = 84;
assert score > 85 : "是小于85的数";
}
}
/**
-ea 表达开启断言,-da表示关闭断言,默认是关闭的
javac Hi.java
java -ea Hi
result
Exception in thread "main" java.lang.AssertionError: 是小于85的数
at Hi.main(Hi.java:22)
*/
public class Hi
{
public static void main(String[] args)
{
int score = 84;
assert score < 85;
}
}