疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java SE 7 异常处理


 

   

  Java SE 7 在日常编程中对一些内容进行了优化

  具体有以下几种

  1、switch 语句中支持字符串String

  如:switch(“a")

  2、更好的整型字符串

  3、泛型改进类型推断<>

  4、优化了异常处理

  5、简化了可变参数方法调用

  我这次主要说的是优化的异常处理具体内容是:多重捕获、重新抛异常和try -with -resources。

  1、多重捕获异常

  JAVA SE7中新增了多重捕获异常,以便更轻松更简洁的处理异常。以后淘宝线上服务器都切换到JAVA 7的时候,我们新代码就可以使用这种特性了。

  现在我们写一段代码进行多重捕获异常是这样的

  示例1

  publicclass Test1 {

  publicstaticvoid main(String[] args) {

  try{

  XXX()xx = newXXXX();

  xx.xxx();

  }catch(ParseException exception){

  }catch(IOException exception){

  }catch(ProduceExceptionexception){

  }

  }

  }

  比如我们这三个异常中,ParseException异常和IOException的业务处理是一致的情况下,要么拷贝同样的代码一份写在一个异常中,要么就使用不同的业务逻辑。如果是在偷懒或者不考虑资源消耗的情况下直接使用

  class Test2 {

  publicstaticvoid main(String[] args) {

  try{

  XXX()xx = newXXXX();

  xx.xxx();

  }catch(Exception exception){

  }

  }

  }

  那么在Test2这个类中,存在的最大问题就是try代码块中的任何代码都会出现异常,而该异常将被一个覆盖式的catch Exception 子句吞掉了。如果抛出的异常不是ParseException异常和IOException,而是其他的异常,在Test2中仍然会捕获它,而上游调用代码不知道实际发生了什么。而这种异常吞并会很难对问题进行处理活着调试(如果业务不确定异常或者异常可以统一处理时,可以直接使用的)

  那么在JAVA 7中,就允许开发者将catch子句组合在一起,而无需在让存在一致的异常处理进行copy了。

  class Test3 {

  publicstaticvoid main(String[] args) {

  try{

  XXX()xx = newXXXX();

  xx.xxx();

  }catch(ParseException | IOException exception){

  }

  }

  }

  Test3类中显示的将两条语句合并成一个catch块,那么在catch时将同时捕获这两种异常;因此,如果业务出现两种异常使用同一处理时就可以使用此方法了。

  语法时:ParseException | IOException exception

  2、重新抛出异常

  在执行异常处理时,有时会重新抛出已经处理过的异常或者当前不处理这个异常直接抛出。通常在偷懒或者经验不足的时候会这么写

  class Test4 {

  publicstaticvoid main(String[] args) {

  try{

  createTest();

  }catch(IOException exception){

  System.err.println(exception.getMessage());

  }

  }

  publicstaticvoid createTest() throws Exception{

  try{

  Test4 test = new Test4();

  test.notifyAll();

  }catch(Exception e){

  throwe;

  }

  }

  }

  在执行Test4是无法编译的

  class Test5 {

  publicstaticvoid main(String[] args) {

  try{

  createTest();

  }catch(RuntimeException exception){

  System.err.println(exception.getCause().getMessage());

  }

  }

  publicstaticvoid createTest() throws Exception{

  try{

  thrownew IOException("Error");

  }catch(IOException e){

  thrownew RuntimeException(exception);

  }

  }

  }

  Test5中显示了一种处理异常然后将其重新抛出的方法,当然在Test5中也是有问题的,是没有把最原始的异常抛出来,而是嵌套在另一个异常中,这意味着下游调用或者依赖方在使用该方法时需要知道原始异常被嵌套的。

  所以这样处理也是不够友好的。如果要给调用方原始异常,那么就需要做一下改动,看下面的例子:

  class Test6 {

  publicstaticvoid main(String[] args) {

  try{

  createTest();

  }catch(IOException exception){

  System.err.println(exception.getCause().getMessage());

  }

  }

  publicstaticvoid createTest() throws Exception{

  try{

  thrownew IOException("Error");

  }catch(IOException e){

  thrownew RuntimeException(exception);

  }

  }

  }

  3、Try-with-Resources

  在使用异常处理时,经常会发现一个问题,就是对资源关闭的时候,如jdbc需要关闭Connection链接;

  如例子(这个代码是我用来给测试做批量的报名数据时使用的)

  publicclass Test {

  publicstaticvoid main(String[] args) {

  Connection conn = null;

  String sql;

  String url = "jdbc:mysql://XXXXX:XXXXX/XXXXX?" + "user=root&password=root&useUnicode=true&characterEncoding=GBK";

  try {

  Class.forName("com.mysql.jdbc.Driver");//

  conn = DriverManager.getConnection(url,"XXXX","XXXX");

  Statement stmt = conn.createStatement();

  for(inti=0;i<10000;i++){

  sql = "INSERT INTO bop_libra_00.bm_application_0093 "

  + "(application_id) "

  + "VALUES "

  + "(10228"+i+"0605)";

  intresult = stmt.executeUpdate(sql);

  System.out.println(result);

  }

  } catch (SQLException e) {

  e.printStackTrace();

  } catch (ClassNotFoundException e) {

  e.printStackTrace();

  } finally {

  try {

  conn.close();

  } catch (SQLException e) {

  // TODO Auto-generated catch block

  e.printStackTrace();

  }

  }

  }

  }

  在上面的代码中,是JAVA SE 7之前的处理关闭资源的一种方式。

  大家看到这里也注意到了一个问题,那就是conn在关闭的时候其实是在try catch外在加了一层处理逻辑,如果我们只想做之事在发送SQLException时对conn进行关闭呢?那么是不是需要写很多的逻辑代码?

  那么在JAVA SE 7的时候我们该怎么做呢?是可以更简洁的完成,可以使用JAVA SE 7中新的语法,可以声明作为try块的组成部分的资源。这样其实也意味着预先考虑到资源的消耗,在程序运行时将在执行try 代码块后自动关闭资源,前提是如果尚未关闭等。

  publicclassTest1 {

  publicstaticvoid main(String[] args) {

  Connection conn = null;

  String sql;

  String url = "jdbc:mysql://XXXXX:XXXXX/XXXXX?" + "user=root&password=root&useUnicode=true&characterEncoding=GBK";

  try(conn = DriverManager.getConnection(url,"XXXX","XXXX")){

  Class.forName("com.mysql.jdbc.Driver");//

  Statement stmt = conn.createStatement();

  for(inti=0;i<10000;i++){

  sql = "INSERT INTO bop_libra_00.bm_application_0093 "

  + "(application_id) "

  + "VALUES "

  + "(10228"+i+"0605)";

  intresult = stmt.executeUpdate(sql);

  System.out.println(result);

  }

  } catch(SQLException | ClassNotFoundException e) {

  e.printStackTrace();

  }

  }

  }

  Test1类的实际的打开操作是发生在try (….) 语句中。当然实现这个代码的前提是需要实现AutoCloseable接口才可以

  总结

  JAVA SE 7中的异常处理更改不仅可以使开发的代码更简洁,还允许对部分异常进行预处理,然后再出现异常的时候进行调用。还能使得在异常清理操作时减少再次异常的出现,新的异常处理可以使得开发人员的效率提高和避免一些特殊的业务处理