有效使用try-catch块和&我们应该在哪里找到它们?

时间:2013-11-09 21:30:39

标签: java try-catch

我有一个接口类,一个实现类,一个异常类和Main类。我不确定我是否有效地在代码中使用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 个答案:

答案 0 :(得分:1)

通常,try / catch块比使用if / else块更昂贵。

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

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

答案 1 :(得分:1)

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

使用类似的代码,除非您使用catch (DatabaseAlreadyExistsException e)

明确地捕获异常,否则您无法捕获异常

除此之外,您还有许多错误处理问题,不建议这样做......打印#StackStackTrace&#39;是不是一个有效的方法来处理问题,但我不确定你是否这样做只是为了表明你已经处理它,或者没有(即你真正的代码只是做一个printStackTrace?)..... < / p>


编辑:评论后更新...

好的,我现在比你以前更了解你的要求。使用其他答案和评论中描述的机制,我建议做类似的事情:

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

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

if (!checkDatabaseExists(...)) {
    createDatabase(...);
}    

答案 2 :(得分:1)

在任何编程论坛中开始宗教战争的简单方法是:&#34;处理错误的最佳方法是什么?&#34; :)但这是一个非常有效的问题。

在Java中,您可能已经知道,有两种例外:运行时可检测和编译时可检测。 (另一组标签是#34;未经检查&#34;,对于运行时,&#34;已检查&#34;,用于编译时。)编译时可检测的异常抛出了专门为它们定义的异常,就像你和#39;重新使用自定义数据库异常。检查和未检查的异常(例如:空指针或索引超出范围异常)的大差异是检查的异常是必需如果被抛出或被委托给方法的范围处理使用&#34; throws&#34;关键字,强制调用方法来处理它。可以处理未经检查的(通过try / catch块),但不是必需的。未经检查的异常也只抛出特定的异常,来自RuntimeException类,它本身就是Exception的后代。 (有关完整的低位,请参阅http://docs.oracle.com/javase/7/docs/api/java/lang/RuntimeException.html)。虽然您可以使用try / catch块来捕获运行时异常,但是您不能将这些异常转换为由其特定运行时异常以外的任何其他异常处理(例如,运行时的空指针引用只能由a处理) NullPointerException对象或其超类对象之一,没有别的。)

为什么&#34;例外审查课程&#34;?因为是否应该抛出异常&#34;向上&#34;调用方法或在其发生的方法中的现场处理在很大程度上与下面的异常生成代码之后的代码是否能够存活的问题有关。没有成功完成try / catch块中的任何内容。后续代码本质上是否会留下可能未经检查(运行时)的异常,如空指针异常?通常情况就是这样。或者,后续代码可以是可执行的,但是处于不可靠状态(例如:未按期望设置的字段值等)。或者,在围绕调用数据库进行更新的try / catch块之类的情况下,数据库数据状态可能不正确。您需要根据上下文和目标(以及依赖关系)决定是否:

  1. 向上抛出异常而不在本地处理或报告,实质上是在调用方法的负担来处理它。
  2. 在本地处理异常并记录/报告(可能),然后使用&#39; return&#39;退出方法。在catch(){}块内。
  3. 在本地处理异常并记录/报告(可能),然后继续执行方法中的代码。
  4. 正如我所说,你所做的,取决于你需要做什么。就个人而言,我认为异常处理是每个给定方法的问题,需要在本地处理。抛出的异常确实意味着该方法无法完成其预期的任务 - 除非调用方法可以弥补其失败,或者在异常创建方法中,后续代码仍然可以实现所需的目标。把它扔到调用方法只是意味着你从表中取出这两个选项中的一个,更糟糕的是,当它发生时会立即抛出 ,所以你在异常之后拿走了任何选择在退出方法之前使用&#39; return&#39;或继续使用该方法。现在有时你可能需要使用try / catch来测试代码中的条件;即,使用某种方法的异常抛出性质作为确定您的代码接下来要做什么的一种方法。然而,这通常是不赞成的,尤其是如果一个&#34;清洁&#34;方式可用。 [没有像纯粹主义者这样的纯粹主义者。 :)]

    当然可能有时候向上抛出异常是好的。但IMO,当调用方法不必太关注受调用方法逻辑影响的任何对象或数据的状态时。我认为这是一种更简洁的方式来处理出现的不太重要的异常。在我自己的情况下,我更喜欢在使用潜在的null对象之前检查很多空对象引用。由于方法中的异常而将可返回对象赋值为null并将其返回到catch(){}块中是一种非常常见的技术,用于让调用方法知道被调用方法无法执行它的意图。 E.g:

    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。如果它返回&#39; true&#39;,则创建数据库。如果&#39; false&#39;,那不是出于某种原因。您还可以让它返回一个int,并根据其值,它指示数据库创建是否成功。例如,值为0可能意味着成功,而值1..n可能表示失败原因,当然一个值表示数据库已经存在。

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

答案 3 :(得分:0)

一般情况下,如果您无法处理现在所处级别的错误,则只会抛出异常,并且只捕获可以在该级别处理的错误。