我已从此developer guide on Content Providers.
的第5个代码段中获取以下代码段令人困惑的是,在第一个语句String[] mSelectionArgs = {""};
中,mSelectionArgs[0]
设置为""
。
稍后如果mSearchString
为空(TextUtils.isEmpty(mSearchString)
),则会再次mSelectionArgs[0]
""
。{/ p>
所以问题是,当它已经初始化为空字符串时,为什么要将它设置为空字符串?
/*
* 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;
}
...
答案 0 :(得分:3)
我喜欢它,因为它是对称的
if something
var = x
else
var = y
很清楚var
在每种条件下是什么,而无需返回并访问其初始值。
答案 1 :(得分:2)
除了额外的清晰度和代码可读性之外,正如另一个答案所述,这种编码风格使代码更容易出错,更容易维护。
这样,如果更改mSelectionArgs
的初始值,或添加了在执行if-else
块之前覆盖此值的新代码,则此块的代码仍将正确执行。没有这个"基本的"分配,如上所述的变化可能导致一个很难追查的错误。
作为旁注:
此特定代码段并不是那么好(是的,我知道它来自Android开发者网站...) - 如果您将null
作为selection
参数传递给query()
,那么最好还将null
作为selectionArgs
参数传递。我将此示例修改为类似的内容(将selection
和selectionArgs
都设置为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};
}
编辑:为什么上面的代码段比原来的更好?
将null作为selection
传递并将非null传递为selectionArgs
并非错误。此数组将传递给您正在寻址的特定ContentProvider
,并且由于selection
不包含任何?
占位符,因此不应该使用该数组。违反此假设的任何ContentProvider
都是错误的。虽然不是错误,但它看起来很奇怪 - 为什么你传递一个应该被忽略的对象?这也有性能成本(如果ContentProvider
在不同的进程中运行,则会更高),这与传递的对象的大小成正比。
编辑2:为什么上面的代码段比原始代码段好多了? 事实证明,我上面所说的可能会产生误导。我发现它很难:
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
中的这两种方法归咎于#34;责备"对于这个例外:
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
个占位符的数量。