Java异常的面试问题及答案-Part 3

Java提供了一个健壮的、面向对象的方法来处理出现异常,称为Java异常处理。 今天我将列出一些重要的Java异常面试的问题及答案,希望对你们的面试有所帮助。这是这个主题的第三篇。第一篇请猛击<a href=”http://www.importnew.com/7383.html”>这里</a>,第二篇请猛击<a href=”http://www.importnew.com/7541.html”>这里</a>

14.提供一些Java异常处理的最佳实践。

答:有关Java异常处理的相关最佳实践如下:

  • 使用具体的异常方便调试
  • 程序中早点抛出异常
  • 捕获异常后先让调用者处理异常
  • 使用Java 7 ARM功能确保资源关闭或者用finally子句正确地关闭它们
  • 为了调试需要总是记录异常信息
  • 用多个catch子句实现更完全的关闭
  • 你自己的应用API中用自定义的异常来抛出单种类型异常
  • 遵循命名规定,以异常结束
  • 在Javadoc中用@throws来标注方法抛出的异常
  • 处理异常是有花销的,因此只有在必要时才抛出。否则,你会扑空或毫无收获。

15.下面的程序中有什么问题,该怎么去修改?

答:这里将针对一些跟异常相关的编程问题:

A.下面这段代码有什么问题呢?

package com.journaldev.exceptions;
import java.io.FileNotFoundException;
import java.io.IOException;

public class TestException {
	public static void main(String[] args) {         
		try {             
			testExceptions();
		} catch (FileNotFoundException | IOException e) {
			e.printStackTrace();
		}
	}

	public static void testExceptions() throws IOException,
			FileNotFoundException {
	}
}

上面这段代码将不能被编译,并且会得到:The exception FileNotFoundException is already caught by the alternative IOException这样的错误信息,这是因为FileNotFoundException是IOException的子类。有两种方法来解决此问题:第一种是用两个catch子句来处理这两个异常。代码如下:

try {     
	testExceptions(); 
}catch(FileNotFoundException e){
	e.printStackTrace(); 
}catch (IOException  e) {
	e.printStackTrace(); 
}

另一种方法就是在catch子句中移除FileNotFoundException,只用IOException。如:

try {
     testExceptions(); 
}catch (IOException  e) {
     e.printStackTrace(); 
}

你可以根据自己的catch子句情况选择上面的任一方法。

B.下面这段代码又有什么问题呢?

 

package com.journaldev.exceptions;   

import java.io.FileNotFoundException; 
import java.io.IOException;   
import javax.xml.bind.JAXBException;   

public class TestException1 {
       public static void main(String[] args) {
             try {
                 go();
             } catch (IOException e) {
                 e.printStackTrace();
             } catch (FileNotFoundException e) {
                 e.printStackTrace();
             } catch (JAXBException e) {
                 e.printStackTrace();
             }
     }

       public static void go() throws IOException, JAXBException, FileNotFoundException{
        }
 }

跟A代码一样,代码将不能编译,因为FileNotFoundException是IOException的子类,所以,FileNotFoundException的catch子句将被隐藏,同时,你会得到这样的:Unreachable catch block for FileNotFoundException.的错误信息。因为异常已被IOException的catch子句处理。你需要改变catch子句的顺序来修复程序。代码如下:

try {
  go();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JAXBException e) {
e.printStackTrace();
}

JAXBException跟FileNotFoundException和IOException不相关,它能放在catch块层级的任何位置。

C.下面的代码同样存在问题。

package com.journaldev.exceptions;
import java.io.IOException;   
import javax.xml.bind.JAXBException;   

public class TestException2 {
       public static void main(String[] args) {
         try {
             foo();
         } catch (IOException e) {
             e.printStackTrace();
         }catch(JAXBException e){
             e.printStackTrace();
         }catch(NullPointerException e){
             e.printStackTrace();
         }catch(Exception e){
             e.printStackTrace();
         }
     }       

      public static void foo() throws IOException{

       }
 }

这段代码同样不能编译,因为JAXBException是个受检查的异常,而foo方法应该抛出此异常供调用方法捕获。你将会得到:Unreachable catch block for JAXBException这样的错误信息。这个异常不可能从try子句中抛出。为解决这个错误,只能将JAXBException从catch子句中移除。

也要注意到,NullPointerException的异常捕获是有效的,因为它是个不被检查的异常。

D.下面的代码存在什么问题呢?

 

package com.journaldev.exceptions;

public class TestException3 {
       public static void main(String[] args) {
         try{
         bar();
         }catch(NullPointerException e){
             e.printStackTrace();
         }catch(Exception e){
             e.printStackTrace();
         }
                   foo();     
       }

       public static void bar(){

        }

          public static void foo() throws NullPointerException{
         } 
}

这代码是个幌子,根本没问题,能被正确编译。我们能捕获到一般异常或者是不被检查的异常,即使在throws语句中没被提及。

同样,如果程序中的一个方法foo()在throws中声明了不被检查的异常,程序中也不一定要处理这个异常。

E.下面这段代码同样存在瑕疵。

package com.journaldev.exceptions;

import java.io.IOException;   

public class TestException4 {
       public void start() throws IOException{

       }

        public void foo() throws NullPointerException{     } 
}  

 class TestException5 extends TestException4{
           public void start() throws Exception{     }
           public void foo() throws RuntimeException{
               } 
}

这段代码不能被编译,因为父类中start的方法签名与子类中的start方法签名不相同。为纠正这错误,我们可以修改子类的方法签名使之与超类相同,我们也可以像下面代码那样移除子类中throws关键字。

@Override    
public void start(){

}

F.下面的代码存在什么问题呢?

package com.journaldev.exceptions;
import java.io.IOException;   
import javax.xml.bind.JAXBException;   

public class TestException6 {
       public static void main(String[] args) {
         try {
             foo();
         } catch (IOException | JAXBException e) {
             e = new Exception("");
             e.printStackTrace();
         }catch(Exception e){
             e = new Exception("");
             e.printStackTrace();
         }
     }

       public static void foo() throws IOException, JAXBException{
               }
 }

这段代码同样不能编译,因为在多个catch子句中的异常对象是不可变的,我们不能改变其值。你会得到这样的:The parameter e of a multi-catch block cannot be assigned编译时错误信息。我们需要删掉将e赋值给新异常对象这句来修正错误。

想了解更多关于Java7多个catch子句的细节,请猛点这里

这就是所有异常面试的问题,希望你们能喜欢。同时,我也希望将来能在列表中添加更多的问题,以适应未来的需要。

原文链接: Journaldev 翻译: ImportNew.com - 韩远青
译文链接: http://www.importnew.com/7820.html
[ 转载请保留原文出处、译者和译文链接。]



相关文章

发表评论

Comment form

(*) 表示必填项

还没有评论。

跳到底部
返回顶部