安卓系统和非法状态异常

3

如果我正在执行一段需要多个变量非空的代码块,例如在内容提供程序delete()函数中,我是否可以抛出一个IllegalStateException异常?

public int delete(Uri uri, String where, String[] whereArgs) {
    try {
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        int count;
        switch (sUriMatcher.match(uri)) {
            case NOTES:
                count = db.delete(NOTES_TABLE_NAME, where, whereArgs);
                break;

            case NOTE_ID:
                String noteId = uri.getPathSegments().get(1);
                count = db.delete(NOTES_TABLE_NAME, NoteColumns._ID + "=" + noteId
                    + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
                break;

            default:
               throw new IllegalArgumentException("Unknown URI " + uri);
       }

       getContext().getContentResolver().notifyChange(uri, null);
       return count;

    } catch (NullPointerException e) {
       // We really shouldn't get any null pointers!
       throw new IllegalStateException();
    }
}

因为,尽管可能性很小,以下变量有可能是 NULL:

- mOpenHelper
- db
- getContext()
- getContentResolver()

这算不算对 IllegalStateException 的滥用呢?我想这么做是因为在我看来,这个函数仅仅抛出 NullPointerExceptions 是错误的。


3
个人而言,我更喜欢带有完整堆栈跟踪的 NPE,以便了解导致它的原因。如果您想要将实现隐藏在用户之外但仍希望在出现错误时进行通信,我建议积极检查 null 或无效参数,并在那里使用无效参数和其他有用信息抛出异常。 - Geert Weening
如果调用者是一个Activity:你可以这样写try{ getContentResolver().delete(myUri, myWhere, myWhereArgs); } catch (NullPointerException e) { // 处理e的异常 }。 - Umbungu
1
dbgetContext()getContentResolver() 不能返回 nullmOpenHelper 是指向你自己的类的引用,如果在提供程序中正确实例化它,我不知道它怎么可能是 null - user
2个回答

1
为什么不创建自己的异常?
public class MyCustomException extends NullPointerException {

    private static final long serialVersionUID = 1L;

    public Exception innerException;

    public MyCustomException() {}

    public MyCustomException(Exception innerException) {
        this.innerException = innerException;
    }
}

...

if (mOpenHelper == null){thrown new MyCustomException("mOpenHelper is null!");}

或者,只需捕获NPE,找出原因,然后抛出自己的异常。

1

最起码,使用throw new IllegalStateException(e);来保留首次异常发生的原因信息。

我个人会确保在需要使用它们之前,所有必需的变量(如mOpenHelper等)都已经正确初始化,以确保NPE不会发生。


我同意 - 我正在努力确保不会发生 NPE。然而,我想加入一个显式的检查以防万一(因为永远不能说永远!)。 - Umbungu
1
@Mewzer 我认为下一个问题是:如果你遇到空指针异常,你能否恢复?如果可以,就捕获并恢复;如果不能,请让它冒泡并在最高层捕获以提供“意外错误 blabla”提示。 - assylias
谢谢 - 在这种情况下,如果其中任何一个为空,那么恢复就不可能了。 - Umbungu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接