java异常处理中throw和throws的区别
首先:
1.用户程序自定义的异常和应用程序特定的异常,必须借助于 throws 和 throw 语句来定义抛出异常。
1.1 throw是语句抛出一个异常。
语法:throw (异常对象);
throw e;
1.2 throws是方法可能抛出异常的声明。(用在声明方法时,表示该方法可能要抛出异常)
语法:[(修饰符)](返回值类型)(方法名)([参数列表])[throws(异常类)]{......}
public void doA(int a) throws Exception1,Exception3{......}
2.接着我们来看一段代码:
main函数:
public static void main(String[] args) { try { exceptionTest("d:\\a","d:\\c"); }catch (Exception e){ System.out.println(e); } }
异常测试函数:
public static void exceptionTest(String inputFileName,String outputFileName) { try { int a=1/0; }catch (Exception e){ System.out.println("出现数字运算异常"); throw e; } }
这是一段最普通的异常处理代码,程序输出结果为
在exceptionTest函数中,我们的try代码块中出现了分母为0的情况,此时jvm会抛出一个ArithmeticExcepiton的异常,接着我们在catch语句找那个使用Exception这个父类(默认能捕获所有异常)捕获到了异常,此时我们打印出了出现数字运算异常,并将此异常对象抛出,给上层方法体接受处理,即主函数处理,主函数捕捉到exceptionTest抛出的异常后,将改异常打印出来。
3.throws关键字是声明在方法体上的,表示该方法可能会抛出某种类型的异常(但并非一定抛出)
我们修改exceptionTest的代码,修改如下:
主函数(不变)
//以文件流的方式读写文件 public static void main(String[] args) { try { exceptionTest("d:\\a","d:\\c"); }catch (Exception e){ System.out.println(e); } }
异常测试函数
public static void exceptionTest(String inputFileName,String outputFileName) { try { //文件异常测试 BufferedInputStream bufferedInputStream=new BufferedInputStream(new FileInputStream("d:\\a.txt")); // String className="com.demo"; Class clazz=Class.forName(className); }catch (Exception e){ System.out.println("出现文件读取异常和类名获取异常"); throw e; } }
这个时候我们运行程序,编译器会报错,直接编译不通过,如果我们把exceptionTest中的throw e给注释了
即修改exceptionTest代码为:
public static void exceptionTest(String inputFileName,String outputFileName) { try { //文件异常测试 BufferedInputStream bufferedInputStream=new BufferedInputStream(new FileInputStream("d:\\a.txt")); // String className="com.demo"; Class clazz=Class.forName(className); }catch (Exception e){ System.out.println("出现文件读取异常和类名获取异常"); // throw e; } }
此时再运行程序,编译通过,程序输出为:
![]()
未注释之前编译器直接报错,编译器的提示是:
Unhandled exceptions: java.io.FileNotFoundException, java.lang.ClassNotFoundException
那是因为我们的方法中有未处理的两个异常,我们可以捕捉他们,然后输出信息到控制台
但是此时我们要用throw e将此异常抛出给上层方法体,必须在方法的声明中用throws FileNotFoundException,ClassNotFoundException来处理
即修改exceptionTest的的代码为:
public static void exceptionTest(String inputFileName,String outputFileName) throws FileNotFoundException, ClassNotFoundException { try { //文件异常测试 BufferedInputStream bufferedInputStream=new BufferedInputStream(new FileInputStream("d:\\a.txt")); // String className="com.demo"; Class clazz=Class.forName(className); }catch (Exception e){ System.out.println("出现文件读取异常和类名获取异常"); throw e; } }
必须要在方法体中声明这两个异常,是因为我们在try的代码块中调用的两个方法中声明了这两个异常,
首先是
new FileInputStream("d:\\a.txt")),
我们看下这个类的源码:
* @param name the system-dependent file name. * @exception FileNotFoundException if the file does not exist, * is a directory rather than a regular file, * or for some other reason cannot be opened for * reading. * @exception SecurityException if a security manager exists and its * <code>checkRead</code> method denies read access * to the file. * @see java.lang.SecurityManager#checkRead(java.lang.String) */ public FileInputStream(String name) throws FileNotFoundException { this(name != null ? new File(name) : null); }
新建一个文件输出流中,构造函数的方法体上已经用throws声明了FileNotFoundException这个异常
Class.forName(className)这个方法中,我们再看Class.forName这个静态函数的源码:
* {@code X} to be initialized. * * @param className the fully qualified name of the desired class. * @return the {@code Class} object for the class with the * specified name. * @exception LinkageError if the linkage fails * @exception ExceptionInInitializerError if the initialization provoked * by this method fails * @exception ClassNotFoundException if the class cannot be located */ @CallerSensitive public static Class<?> forName(String className) throws ClassNotFoundException { Class<?> caller = Reflection.getCallerClass(); return forName0(className, true, ClassLoader.getClassLoader(caller), caller); }
改方法上也用throws声明了ClassNotFoundException这个异常,
所以外层方法体调用他们的时候必须要对他们进行try-catch,
同样我们在testExcepiton函数中捕捉完后,想将改异常抛出,则必须在方法体中声明异常的类型,
然后再交由上层方法体处理。
总结:
throws只是在方法上的声明,表示函数可能会抛出改异常
throw是抛出实际的异常,如果在try的代码块中使用可能会抛出异常的函数,catch捕获后想要再次抛出给上层方法体,则需要再方法体上再次声明。



浙公网安备 33010602011771号