1

我有一个接口类、一个实现类、一个异常类和一个主类。我不确定我是否在我的代码中有效地使用了 try catch 块。我在网上搜索并找到了类似的主题和问题,但我找不到我的问题的答案。我在主文件和实现文件中都使用了 try catch。有意义吗?能请教一下效果吗?以下关于 try-catch 的逻辑是否正确?

Interface Class:

public void createDatabase() throws DatabaseAlreadyCreated;


Implementation Class:

public void createDatabase() throws DatabaseAlreadyCreated
{
try
{
   // Create Database 
       //if database is already exist 
      throw new DatabaseAlreadyCreated();
}         
catch (SQLException e) {e.printStackTrace();} 
catch (ClassNotFoundException e) {e.printStackTrace();}

}

 Exception Class:

 public class DatabaseAlreadyExist extends Exception
 {

    public DatabaseAlreadyExist(String str)
    {
       System.out.println("database exist exception");
    }
 }



 Main Class:

 public static void main(String args[])
 {
       try 
       {
       x = ops.createDatabase();
       } 
       catch (DatabaseAlreadyExist e) 
       {
         e.printStackTrace();
   }
 } 
4

4 回答 4

1

一般来说,try/catch 块比使用 if/else 块更昂贵。

所以只使用 try/catch 可能会发生实际错误,例如在与服务器或数据库通信时,try/catch 块是合适的。

如果应该测试一个变量是否为“null”,那么使用 try/ctach 会很昂贵。在这些情况下,您应该使用 if/else 之类的逻辑。

于 2013-11-09T21:43:38.867 回答
1

代码有些损坏......除非您有非常具体的原因,否则您永远不应该直接扩展Throwable该类,而是应该扩展Exception(或像 RuntimeException 这样的 Exception 的后代)。

使用这样的代码,除非您明确地捕获它,否则您不太可能捕获异常catch (DatabaseAlreadyExistsException e)

除此之外,您还有一些不推荐的错误处理问题......执行“printStackTrace”不是处理问题的有效方法,但我不确定您这样做是否只是为了表明您有没有处理它(即你的真实代码只是做一个 printStackTrace 吗?).....


编辑:评论后更新...

好的,我比以前更了解您现在的要求。使用其他答案和评论中描述的机制,我建议执行以下操作:

public boolean checkDatabaseExists(...) {
    try {
        ... do the things you need to check the database exists.
        return true;
    } catch (Exception e) {
        return false;
    }
}

然后,在您的主要方法中,您可以:

if (!checkDatabaseExists(...)) {
    createDatabase(...);
}    
于 2013-11-09T21:44:48.380 回答
1

在任何编程论坛中发起宗教战争的简单方法是:“处理错误的最佳方法是什么?” :) 但这是一个完全有效的问题。

在 Java 中,您可能已经知道,有两种异常:运行时可检测和编译时可检测。(另一组标签是“未检查”,用于运行时,“已检查”,用于编译时。)编译时可检测异常已抛出专门为它们定义的异常,就像您对自定义数据库异常所做的那样。检查和未检查异常(例如:空指针或索引超出范围异常)之间的最大区别是需要检查异常如果抛出或使用“throws”关键字将其委托到方法的范围之外,则进行处理,从而强制调用方法对其进行处理。可以处理未选中的(通过 try/catch 块),但这不是必需的。未经检查的异常也只抛出特定的异常,它们是 RuntimeException 类的后代,它本身是 Exception 的后代。(请参阅http://docs.oracle.com/javase/7/docs/api/java/lang/RuntimeException.html了解完整的低调)。虽然您可以使用 try/catch 块来捕获运行时异常,但您不能将这些类型的异常转换为由它们特定的运行时异常以外的任何东西处理(例如,运行时的空指针引用只能由 NullPointerException 对象处理或其超类对象之一,仅此而已)。

那么为什么要上“例外复习课”呢?因为一个异常是否应该被“向上”抛出给调用方法,或者在它发生的方法中就地处理,在很大程度上与异常生成代码之后的代码是否可以“生存”而没有成功完成 try/catch 块中的任何内容。后续代码本质上是否会留下可能的未检查(运行时)异常,例如空指针异常?很多时候,情况就是这样。或者,后续代码可能是可执行的,但处于不可靠状态(例如:未按需要设置的字段值等)。或者,在调用数据库以进行更新时出现诸如 try/catch 块之类的情况,数据库数据状态可能不适合您想要完成的操作。

  1. 向上抛出异常而不在本地处理或报告它,实质上将处理它的负担放在调用方法上。
  2. 在本地处理异常并记录/报告(可能),然后在 catch () {} 块中使用“return”退出该方法。
  3. 在本地处理异常并记录/报告(可能),然后继续执行方法中的代码。

正如我所说,你做什么取决于你需要做什么。就个人而言,我认为异常处理是每个给定方法的问题,需要在本地处理。抛出异常实际上意味着该方法未能完成其预期任务——除非调用方法能够弥补其失败,或者在异常创建方法内,后续代码仍然可以完成预期目标。将它扔给调用方法只是意味着您将这两个选项中的一个从桌面上拿走,更糟糕的是,它会立即被抛出当它发生时,所以在使用“return”退出方法或继续使用该方法之前,您可以取消在异常之后拾取的任何选项。现在有时可能需要使用 try/catch 来测试代码中的条件;即,使用某些方法的异常抛出特性来确定您的代码接下来会做什么。然而,这通常是不受欢迎的,尤其是。如果有“更清洁”的方式可用。[没有像 Java 纯粹主义者这样的纯粹主义者。:)]

当然,有时向上抛出异常是可以的。但是在 IMO 中,调用方法不需要太关心受调用方法逻辑影响的任何对象或数据的状态。我认为它是一种更简单的方式来处理出现的不太重要的异常。在我自己的情况下,我更喜欢在使用可能为空的对象之前检查空对象引用。由于方法中的异常而为可返回对象分配 null 值并在 catch () {} 块中返回它是一种非常常见的技术,用于让调用方法知道被调用方法未能完成它的意图. 例如:

public meth1() {
   Object o = meth2();
    if (o != null) {
       ... do what you need to ...
       } else
       {
       ... deal w/ no valid o object ...
       }
     ...
   }

private Object meth2()   {
   Object retnme = new Object();
   ...
   try {
      ... give it yer best ...
   } catch ( Exception e )
   {
      logException(e); // a call to some logging method.
       ... clean up bad karma ...
       return null;
    }
  ...
  return retnme;
}

综上所述,您的直接问题是您的代码:基于上述内容并记住我并不完全了解您的情况,我不明白为什么您应该将您创建的自定义异常抛出给调用方法,除非您特别想使用该异常向您要创建的数据库已经存在的调用方法发出信号,无论出于何种原因。但是,如果知道这对调用方法没有特定用途 - 则无需这样做。这个决定的一部分取决于您是否希望使用任何实现您的接口的类来需要知道数据库是否存在。然而,避免使用这种策略的一种方法是编辑您的接口和类文件,以便该方法返回布尔值而不是 void。如果它返回“true”,则数据库已创建。如果'假',这不是出于某种原因。您还可以让它返回一个 int 并根据它的值指示数据库创建是否成功。例如,值 0 可能意味着成功,而值 1..n 可能表示失败原因,一个值当然表示 db 已经存在的事实。

真的,天空才是极限。:) 希望这对您有所帮助。

于 2013-11-09T23:01:44.800 回答
0

通常,只有在当前级别上无法处理错误时才抛出异常,并且仅捕获可以在该级别处理的错误。

于 2013-11-09T21:34:37.813 回答