Java 当这个变量已经初始化为空字符串时,为什么要将它设置为空字符串?
我从第五段代码中获取了以下代码片段 混淆之处在于第一条语句Java 当这个变量已经初始化为空字符串时,为什么要将它设置为空字符串?,java,android,android-contentprovider,android-contentresolver,Java,Android,Android Contentprovider,Android Contentresolver,我从第五段代码中获取了以下代码片段 混淆之处在于第一条语句String[]mSelectionArgs={”“},mSelectionArgs[0]设置为“” 然后,如果mSearchString为空(TextUtils.isEmpty(mSearchString)),则再次分配mSelectionArgs[0] 所以问题是,当它已经初始化为空字符串时,为什么他们要将其设置为空字符串? /* * This defines a one-element String array to contai
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;
}
...
我喜欢它,因为它是对称的
if something
var = x
else
var = y
在每种情况下,
var
是什么很清楚,无需返回并访问其初始值。除了额外的清晰性和代码可读性,如另一个答案中所述,这种编码风格使得代码更容易维护,更不容易出错
这样,如果更改了mSelectionArgs
的初始值,或者在执行if else
块之前添加了覆盖此值的新代码,则此块的代码仍将正确执行。如果没有这个“基本的”分配,如上所述的更改可能会导致很难跟踪的bug
作为旁注:
这个特定的代码片段不是很好(是的,我知道它来自Android开发者网站…)-如果您将null
作为selection
参数传递给query()
,那么最好也将null
作为selectionArgs
参数传递。我会将此示例修改为类似的内容(将selection
和selectionArgs
设置为null):
编辑:为什么上面的代码片段比原来的好?
/*
* 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;
}
...
将null作为selection
传递和非null作为selectionArgs
传递不是错误。此数组将传递给您正在寻址的特定内容提供程序
,并且不应使用,因为选择
不包含任何?
占位符。任何违反此假设的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
,其中包含的元素数超过选择中的占位符数
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;
}
public void bindallargsassstrings(String[]bindArgs){
if(bindArgs!=null){
对于(int i=bindArgs.length;i!=0;i--){
bindString(i,bindArgs[i-1]);
}
}
}
私有void绑定(int索引,对象值){
如果(索引<1 | |索引>多个参数){
抛出新的IllegalArgumentException(“无法在索引处绑定参数”
+索引+“因为索引超出范围。”
+“该语句有”+mNumParameters+“parameters.”);
}
mBindArgs[索引-1]=值;
}
现在,当我发现这种行为时,我认为Android开发者网站上的代码示例不仅效率低下,而且完全是一堆废话
底线:如果您将null
作为selection
传递,那么也将null
作为selectionArgs
传递。如果selection
不为空且包含?
占位符-请确保selectionArgs
数组的长度等于selection
中的?
占位符的数量,我想这只是为了更清楚。例如,他们正在强调一点,在本例中,如果搜索值为空,mSelectionArgs[0]仍然为“”。但是,谁知道呢。这可能只是一种风格。“如果将null作为选择参数传递给query(),那么最好也将null作为selectionArgs参数传递。”-但为什么?如果selectionArgs
是空字符串(如原始代码段中的字符串),会发生什么情况?(对不起,我是新手)@Solace,我在答案中添加了解释。在您的代码中,您可以将mSelectionArgs
保留为未初始化状态。@bayou.io,是的,但我总是尝试在代码中明确说明。即使Lint抱怨不必要的赋值:)@Solace,我也发现了您引用的代码片段不好的其他原因。答案中的“编辑2”部分对此进行了描述。以防万一你感兴趣。。。