我从这个 developer guide on Content Providers. 的第 5 个 fragment 中获取了以下代码 fragment

令人困惑的是,在第一条语句 String[] mSelectionArgs = {""}; 中, mSelectionArgs[0] 设置为 ""

然后,如果 mSearchString 为空( TextUtils.isEmpty(mSearchString) ),则再次为 mSelectionArgs[0] 分配 ""

那么问题是,当它已经初始化为空字符串时,为什么还要将其设置为空字符串呢?

/*
 * This defines a one-element String array to contain the selection argument.
 */
String[] mSelectionArgs = {""};

// Gets a word from the UI
mSearchString = mSearchWord.getText().toString();

// Remember to insert code here to check for invalid or malicious input.

// If the word is the empty string, gets everything
if (TextUtils.isEmpty(mSearchString)) {
    // Setting the selection clause to null will return all words
    mSelectionClause = null;
    mSelectionArgs[0] = "";

} else {
    // Constructs a selection clause that matches the word that the user entered.
    mSelectionClause = UserDictionary.Words.WORD + " = ?";

    // Moves the user's input string to the selection arguments.
    mSelectionArgs[0] = mSearchString;

}
...

最佳答案

除了额外的清晰度和代码可读性,如另一个答案中所述,这种编码风格使代码不易出错,更易于维护。

这样,如果在 mSelectionArgs 块执行之前更改了 if-else 的初始值,或者添加了覆盖该值的新代码,则该块的代码仍将正确执行。如果没有这种“基本”分配,上述更改可能会导致很难追踪的错误。

作为旁注:

这个特定的代码 fragment 不是那么好(是的,我知道它来自 Android 开发人员网站...) - 如果您将 null 作为 selection 参数传递给 query() ,那么最好也将 null 作为 selectionArgs 参数传递。我会将此示例修改为类似的内容(将 selectionselectionArgs 都设置为 null):

// Gets a word from the UI

mSearchString = mSearchWord.getText().toString();

// Remember to insert code here to check for invalid or malicious input.

String[] mSelectionArgs = null;

// If the word is the empty string, gets everything
if (TextUtils.isEmpty(mSearchString)) {
    // Setting the selection clause to null will return all words
    mSelectionClause = null;
    mSelectionArgs = null;

} else {
    // Constructs a selection clause that matches the word that the user entered.
    mSelectionClause = UserDictionary.Words.WORD + " = ?";

    // Moves the user's input string to the selection arguments.
    mSelectionArgs = new String[] {mSearchString};

}

编辑:为什么上面的代码 fragment 比原来的好?

将 null 作为 selection 传递,将非 null 作为 selectionArgs 传递并不是错误。该数组将传递给您正在寻址的特定 ContentProvider,并且根本不应使用,因为 selection 不包含任何 ? 占位符。任何违反此假设的 ContentProvider 都是错误的。虽然不是错误,但它看起来很奇怪 - 为什么你传递一个无论如何都应该被忽略的对象?这也有性能成本(如果 ContentProvider 在不同进程中运行,则性能成本更高),这与传递的对象的大小成正比。

编辑 2:为什么上面的代码 fragment 比原来的好得多?
事实证明,我上面所说的可能具有误导性。我发现它很难:
 Caused by: java.lang.IllegalArgumentException: Cannot bind argument at index 3 because the index is out of range.  The statement has 1 parameters.
        at android.database.sqlite.SQLiteProgram.bind(SQLiteProgram.java:212)
        at android.database.sqlite.SQLiteProgram.bindString(SQLiteProgram.java:166)
        at android.database.sqlite.SQLiteProgram.bindAllArgsAsStrings(SQLiteProgram.java:200)
        at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:47)
        at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1314)
        at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1161)
        at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1032)
        at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1200)

抛出上述异常是因为我试图传递包含比 selectionArgs? 占位符数量更多的元素的 selection
SQLiteProgram.java 中的这两个方法要“归咎于”这个异常:
public void bindAllArgsAsStrings(String[] bindArgs) {
    if (bindArgs != null) {
        for (int i = bindArgs.length; i != 0; i--) {
            bindString(i, bindArgs[i - 1]);
        }
    }
}

private void bind(int index, Object value) {
    if (index < 1 || index > mNumParameters) {
        throw new IllegalArgumentException("Cannot bind argument at index "
                + index + " because the index is out of range.  "
                + "The statement has " + mNumParameters + " parameters.");
    }
    mBindArgs[index - 1] = value;
}

现在,当我发现这种行为时,我认为来自 Android Developers 站点的代码示例不仅效率低下,而且完全是废话!

底线:如果您将 null 作为 selection 传递,也将 null 作为 selectionArgs 传递。如果 selection 不为空并且包含 ? 占位符 - 确保 selectionArgs 数组的长度等于 ?selection 占位符的数量。

关于java - 为什么这个变量在它已经初始化为空字符串时设置为空字符串?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30813481/

10-10 01:56