1.Error:
2.Exception:
对于这些错误一般有两种解决方法 :
捕获错误最理想的是在编译期间,但有的错误只有在运行时才会发生。
比如: 除数为 0 数组下标越界 等
分类:
编译时异常和运行时异常
编译时异常:
异常体系结构:
java.lang.Throwable (父类)
java.lang.Error:一般不编写针对性的代码进行处理。
java.lang.Exception:可以进行异常的处理
编译时异常(checked)
运行时异常:
运行时异常(unchecked,RuntimeException)
public class ExceptionTest {
//******************以下是编译时异常***************************
@Test
public void test7(){
// File file = new File("hello.txt");
// FileInputStream fis = new FileInputStream(file);
//
// int data = fis.read();
// while(data != -1){
// System.out.print((char)data);
// data = fis.read();
// }
//
// fis.close();
}
//******************以下是运行时异常***************************
//ArithmeticException
@Test
public void test6(){
int a = 10;
int b = 0;
System.out.println(a / b);
}
//InputMismatchException
@Test
public void test5(){
Scanner scanner = new Scanner(System.in);
int score = scanner.nextInt();
System.out.println(score);
scanner.close();
}
//NumberFormatException
@Test
public void test4(){
String str = "123";
str = "abc";
int num = Integer.parseInt(str);
}
//ClassCastException
@Test
public void test3(){
Object obj = new Date();
String str = (String)obj;
}
//IndexOutOfBoundsException
@Test
public void test2(){
//ArrayIndexOutOfBoundsException
// int[] arr = new int[10];
// System.out.println(arr[10]);
//StringIndexOutOfBoundsException
String str = "abc";
System.out.println(str.charAt(3));
}
//NullPointerException
@Test
public void test1(){
// int[] arr = null;
// System.out.println(arr[3]);
String str = "abc";
str = null;
System.out.println(str.charAt(0));
}
}
在编写程序时,经常要在可能出现错误的地方加上检测的代码,如进行 x/y 运算时,要 检测分母为 0 ,数据为空,输入的不是数据而是字符 等。过多 的 if else 分支 会导致程序的 代码 加长、臃肿,可读性 差。因此 采用 异常处理机制 。
Java异常处理
Java采用的异常处理机制 ,是将异常处理的程序代码集中在一起,与正常的程序代码分开,使得程序 简洁、优雅, 并易于维护。
Java异常处理的方式:
方式一:try catch finally
异常处理是通过
try catch finally 语句实现的。
try{
......
可能产生异常的代码
}catch(ExceptionName1 e){
......
当产生 ExceptionName1 型异常时的处置措施
}
catch(ExceptionName2 e){
......
当产生 ExceptionName2 型异常时的处置措施
}finally{
......
无论是否发生异常 都无条件执行的语句
}
public class ExceptionTest1 {
@Test
public void test2(){
try{
File file = new File("hello.txt");
FileInputStream fis = new FileInputStream(file);
int data = fis.read();
while(data != -1){
System.out.print((char)data);
data = fis.read();
}
fis.close();
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
@Test
public void test1(){
String str = "123";
str = "abc";
int num = 0;
try{
num = Integer.parseInt(str);
System.out.println("hello-----1");
}catch(NumberFormatException e){
// System.out.println("出现数值转换异常了,不要着急....");
//String getMessage():
// System.out.println(e.getMessage());
//printStackTrace():
e.printStackTrace();
}catch(NullPointerException e){
System.out.println("出现空指针异常了,不要着急....");
}catch(Exception e){
System.out.println("出现异常了,不要着急....");
}
System.out.println(num);
System.out.println("hello-----2");
}
}
try-catch-finally中finally的使用:
* 1.finally是可选的
* 2.finally中声明的是一定会被执行的代码。即使catch中又出现异常了,try中有return语句,catch中有 return语句等情况。
* 3.像数据库连接、输入输出流、网络编程Socket等资源,JVM是不能自动的回收的,我们需要自己手动的进行资源的释放。此时的资源释放,就需要声明在finally中
public void readFile (String file) throws FileNotFoundException
……
//读文件的操作可能产生 FileNotFoundException 类型的异常
FileInputStream fis new FileInputStream (file);
...
}
注意:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class ExceptionTest2 {
public static void main(String[] args){
try{
method2();
}catch(IOException e){
e.printStackTrace();
}
// method3();
}
public static void method3(){
try {
method2();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void method2() throws IOException{
method1();
}
public static void method1() throws FileNotFoundException,IOException{
File file = new File("hello1.txt");
FileInputStream fis = new FileInputStream(file);
int data = fis.read();
while(data != -1){
System.out.print((char)data);
data = fis.read();
}
fis.close();
System.out.println("hahaha!");
}
}
示例代码:
import java.io.FileNotFoundException;
import java.io.IOException;
/*
* 方法重写的规则之一:
* 子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型
*
*
*/
public class OverrideTest {
public static void main(String[] args) {
OverrideTest test = new OverrideTest();
test.display(new SubClass());
}
public void display(SuperClass s){
try {
s.method();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class SuperClass{
public void method() throws IOException{
}
}
class SubClass extends SuperClass{
public void method()throws FileNotFoundException{
}
}
IOException e new IOException();
throw e;
throw new String("want to throw");
注:
throw 和throws 的区别:throw 是生成一个异常对象的方式,声明在方法体内。
而throws是处理异常的一种方式,声明在方法的声明处。
/*
* 如何自定义异常类?
* 1. 继承于现有的异常结构:RuntimeException 、Exception
* 2. 提供全局常量:serialVersionUID
* 3. 提供重载的构造器
*
*/
public class MyException extends Exception{
static final long serialVersionUID = -7034897193246939L;
public MyException(){
}
public MyException(String msg){
super(msg);
}
}
示例代码:
public class StudentTest {
public static void main(String[] args) {
try {
Student s = new Student();
s.regist(-1001);
System.out.println(s);
} catch (Exception e) {
// e.printStackTrace();
System.out.println(e.getMessage());
}
}
}
class Student{
private int id;
public void regist(int id) throws Exception {
if(id > 0){
this.id = id;
}else{
// System.out.println("您输入的数据非法!");
//手动抛出异常对象
// throw new RuntimeException("您输入的数据非法!");
// throw new Exception("您输入的数据非法!");
throw new MyException("不能输入负数");
//错误的
// throw new String("不能输入负数");
}
}
@Override
public String toString() {
return "Student [id=" + id + "]";
}
}