java - 为什么android.database.DatabaseUtils不会抛出SQLException等异常?

标签 java android database sqlite database-design

我刚开始开发 Android 应用程序,令我感到非常惊讶的是,像 android.database.DatabaseUtils 这样的 API 在使用其方法时不会向上抛出异常。我想知道我认为糟糕的设计的原因是什么。 (一定是有原因的。。)

例如here

使用方法long execute()

public long execute() {

  if (mPreparedStatement == null) {
    throw new IllegalStateException("you must prepare this inserter before calling "+ "execute");
  }
  try {
    if (LOCAL_LOGV) Log.v(TAG, "--- doing insert or replace in table " + mTableName);
    return mPreparedStatement.executeInsert();
  } catch (SQLException e) {
    Log.e(TAG, "Error executing InsertHelper with table " + mTableName, e);
    return -1;
   } finally {
   // you can only call this once per prepare
   mPreparedStatement = null;
  }
}

所以这个方法正在捕获 SQLException,而不是向调用者抛出这个或另一个包装的异常,它只是返回 -1 并使用 logcat 记录错误。

作为一名开发人员,我发现这非常令人震惊,就好像我正在使用这个 API 并且我得到一个值 -1 我知道出了点问题,但我不知道为什么出了问题,除非我检查 logcat 日志。

也许我弄错了,请让我知道,但是一个 API 的方法返回 -1 的操作是一个糟糕的 OO 设计,如果出现问题它可以简单地抛出异常并让开发人员以他/她希望从 Exception 对象中提取所有详细信息的方式处理该异常。你不觉得吗?

有什么理由这样做吗?

我已经将 logback 与我的应用程序集成在一起,我希望不需要为任何事情使用 logcat。但是在看到这个 API 之后,我担心我将不得不以某种方式将过滤后的 logcat 导出到一个文件中,以查看当我的应用程序收到 -1 在 SQLlite 上执行某些操作时出了什么问题。

有什么建议吗?我在这里遗漏了什么吗?

非常感谢!

最佳答案

首先,我们不是最初编写代码的 Google 工程师,也不是介意读者。我们不能确定为什么一段代码是这样设计的。但我们可以做出有根据的猜测。请考虑以下事项:

  • 数据库 API 建立在 sqlite3 C 库之上。 C 没有异常,异常错误条件通过其他方式发出信号,例如返回一个特殊值,例如 -1。

  • 从设计的角度来看,android.database 包中的 API 抛出异常 android.database.sqlite 包会暴露不必要的实现细节。 (尽管还有其他方法通过使用 SQL* 类来公开此类细节。) 如您所述,将详细的异常包装在 API 级异常中会更好。

  • “Utils”类通常不是真正设计的。它们只是开发人员发现经常需要的方法的集合。您不必使用它们。

  • 异常处理在性能方面相对昂贵。返回特殊值要便宜得多。避免异常可能是一个好主意,尤其是在经常执行的低级代码中。虽然这一点与您链接的代码无关,因为它包含一个 try-catch block 。

  • 总的来说,Android sqlite API 的设计并不是特别典型。我之前写过它的一些奇怪之处,例如 here .

关于java - 为什么android.database.DatabaseUtils不会抛出SQLException等异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24729463/

相关文章:

android - 如何更改用于指示已在 TabHost 上选择选项卡的颜色?

android - 如何使用 ViewPager 延迟动态 View 更改?

ruby-on-rails - 具有大量小写入和长读取的 Rails 前端的 PostgreSQL 集群的最低硬件要求和设置是什么?

python - 在 sqlalchemy、数据库、ORM 中使用标签

mysql - 锁(S、X、IS、IX)如何在 Mysql 中使用 FOR UPDATE/LOCK IN SHARE MODE 之类的查询工作?

java - 如何使用 Java 比较器进行排序忽略某些值

java - Java 中的透明度

java - 如果父类(super class)已经完成了clone()方法,子类是否需要显式地重写clone()方法?

Java - 带有边距的 JPanel 和内部的 JTextArea

android - Retrofit 2.0 解析 HTML