Java程序运行时会出现错误(Error)和异常(Exception),错误不能在进行处理,是致命的,异常还可以进行处理。
java中的异常分为两大类:
A)checked exception(非Runtime Exception)
B)Unchecked exception(Runtime Exception)
Java中所有的异常类都会直接或间接继承自Exception;RuntimeException类直接继承自Exception,他叫做运行时异常,java中所有运行时异常都直接或间接继承自RuntimeException。java中凡是继承自Exception而不是继承自RuntimeException的类都是非运行时异常。
1、
异常处理的一般结构:
Try
{
}
Catch(Exception e)
{
}
Finally
{
}
无论程序是否出现异常,finally块中的代码都会被执行的
执行流程:先执行try块中代码,出现异常,终止执行,转到catch,执行完catch后执行finally,如果没有异常,执行完try,执行finally。
2、在方法中可以使用throw new Exception();手工抛出异常。如果在方法中抛出了异常,在方法声明中也要声明抛出异常,在方法声明后加上throws Exception。
对于非运行时异常(checked exception),必须对其进行处理,处理方式有两种:第一种使用try…catch…finally进行捕获;第二种是在调用该会产生异常的方法所在的方法声明throws Exception
[java] view plain copy print ?
- public class ExceptionTest2
- {
- public void method() throws Exception
- {
- System.out.println("hello");
-
- throw new Exception();
- }
-
- public static void main(String[] args)
- {
- ExceptionTest2 test = new ExceptionTest2();
- try
- {
- test.method();
- }
- catch(Exception e)
- {
- e.printStackTrace();
- }
- finally
- {
- System.out.println("world");
- }
- }
- }
public class ExceptionTest2
{
public void method() throws Exception
{
System.out.println("hello");
throw new Exception();
}
public static void main(String[] args)
{
ExceptionTest2 test = new ExceptionTest2();
try
{
test.method();
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
System.out.println("world");
}
}
}
对于运行时异常(RuntimeException),我们可以不对其进行处理,也可以对其进行处理,建议不处理
3、NullPointrException是空指针异常,出现该异常的原因在于某个引用为null,但你却调用了他的某个方法,这时就会出现该异常。
[java] view plain copy print ?
- public class ExceptionTest3
- {
- public static void main(String[] args)
- {
- String str = null;
-
- System.out.println(str.length());
- }
- }
public class ExceptionTest3
{
public static void main(String[] args)
{
String str = null;
System.out.println(str.length());//出现NullPointrException异常
}
}
4、自定义异常:所谓自定义异常,通常就是定义了一个继承自Exception类的子类,那么这个类就是一个自定义异常类。通常情况下,我们都会直接继承自Exception类,一般不会继承某个运行时的异常类。
自定义异常及两种处理方式:
[java] view plain copy print ?
- public class ExceptionTest4
- {
- public void method(String str) throws MyException
- {
- if (null == str)
- {
- throw new MyException("传入字符串不能为null");
- }
- else
- {
- System.out.println(str);
- }
- }
-
-
-
-
-
-
-
-
- public static void main(String[] args)
- {
- ExceptionTest4 test = new ExceptionTest4();
-
- try
- {
- test.method(null);
- }
- catch(MyException e)
- {
- e.printStackTrace();
- }
- finally
- {
- System.out.println("异常处理完毕");
- }
- System.out.println("程序处理完毕");
- }
- }
public class ExceptionTest4
{
public void method(String str) throws MyException
{
if (null == str)
{
throw new MyException("传入字符串不能为null");
}
else
{
System.out.println(str);
}
}
// public static void main(String[] args) throws MyException
// {
// ExceptionTest4 test = new ExceptionTest4();
//
// test.method(null);
// }
public static void main(String[] args)
{
ExceptionTest4 test = new ExceptionTest4();
try
{
test.method(null);
}
catch(MyException e)
{
e.printStackTrace();
}
finally
{
System.out.println("异常处理完毕");
}
System.out.println("程序处理完毕");
}
}
5、我们可以使用多个catch快来捕获异常,这时需要将父类型的catch块放在子类型的catch块之后,这样才能保证后续的catch块可能被执行,否则子类型的catch将永远无法到达,java编译器会报编译错误;如果多个catch块的异常类型是独立的(MyException,MyException2),那么谁前谁后首饰可以的
[java] view plain copy print ?
- public class ExceptionTest5
- {
- public void method(String str) throws MyException,MyException2
- {
- if (null == str)
- {
- throw new MyException("传入字符串不能为null");
- }
- else if("hello" == str)
- {
- throw new MyException2("传入了hello");
- }
- else
- {
- System.out.println(str);
- }
- }
-
-
-
-
-
-
-
-
- public static void main(String[] args)
- {
-
-
- try
- {
- ExceptionTest5 test = new ExceptionTest5();
- test.method("hello");
- }
- catch(MyException e)
- {
- e.printStackTrace();
- }
- catch(MyException2 e)
- {
- e.printStackTrace();
- }
- catch(Exception e)
- {
- e.printStackTrace();
- }
- finally
- {
- System.out.println("异常处理完毕");
- }
- System.out.println("程序处理完毕");
- }
- }
public class ExceptionTest5
{
public void method(String str) throws MyException,MyException2
{
if (null == str)
{
throw new MyException("传入字符串不能为null");
}
else if("hello" == str)
{
throw new MyException2("传入了hello");
}
else
{
System.out.println(str);
}
}
// public static void main(String[] args) throws MyException
// {
// ExceptionTest4 test = new ExceptionTest4();
//
// test.method(null);
// }
public static void main(String[] args)
{
try
{
ExceptionTest5 test = new ExceptionTest5();
test.method("hello");
}
catch(MyException e)
{
e.printStackTrace();
}
catch(MyException2 e)
{
e.printStackTrace();
}
catch(Exception e) //必须放在最后,否则它将拦截所有异常,后面的catch将再无法获得运行时机
{
e.printStackTrace();
}
finally
{
System.out.println("异常处理完毕");
}
System.out.println("程序处理完毕");
}
}
6、如果try块中存在return语句,那么首先也需要将finally块中的代码执行完毕,然后方法再返回,再执行return语句;如果try块中存在System。Exit(0)语句,那么就不会执行finally块中的代码,因为System。Exit(0)会终止当前运行的java虚拟机,程序会在虚拟机终止前结束执行。