我正在使用Android应用,我正在编写并尝试使我的代码完全符合Android Studio的lint推荐。
我有以下代码发出警告(某些代码被省略):
final EditText input = (EditText)view.findViewById(R.id.edit_text);
Button button = (Button)view.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String value = input.getText().toString();
if (value == null || value.length() == 0) {
Android Studio正在向我发出警告:
条件'值== null'总是假的。
当我允许Android Studio修复"对我来说问题,它建议:
简化'值== null'为假
然后代码变为:
if (value.length() == 0) {
我查看了Android源代码(http://www.grepcode.com)并且我很困惑。 EditText
的文档说" EditText是TextView上的薄贴面,它将自身配置为可编辑。"然后,getText()
方法定义如下:
@Override
public Editable getText() {
return (Editable) super.getText();
}
当我转到getText()
寻找TextView
("超级")时,我看到了这一点:
public CharSequence getText() {
return mText;
}
setText()
的{{1}}方法似乎不允许TextView
值,因为这是该方法的开头:
null
默认构造函数也是以这种方式启动的:
private void setText(CharSequence text, BufferType type, boolean notifyBefore, int oldlen) {
if (text == null) {
text = "";
}
因此,似乎public TextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mText = "";
无法返回getText()
值,但this answer上的注释表明它是。null
。 this question的答案似乎也表明它是可能的。
我想练习防御性编码,这就是为什么我按照我从一开始的方式构建代码的原因,但我不想做null
检查不可能是null
。那么,在这种情况下,最佳做法是什么?
答案 0 :(得分:2)
我认为lint检查会告诉你一些不同的东西:
String value = input.getText().toString();
if (value == null || value.length() == 0) {
条件'value == null'始终为false。
在这个if语句中,EditText.getText()
是否可以返回null无关紧要。因为如果它返回null,那么.toString()
会在甚至达到if语句之前导致NullPointerException。因此,如果if语句完全可达,则value不能为null。
您可以通过Android源代码挖掘所有内容,也许您会发现EditText
无法返回null。如果是这种情况,那么如果您知道标准的EditText在您的应用中,则可以忽略lint警告。
但是,在更一般的情况下,没有什么能阻止我在视图层次结构中坚持这个:
public class EvilEditText extends EditText {
// Constructors
@Override
public Editable getText() {
return null;
}
}
所以最安全的选择是将代码重写为完全无效:
Editable e = input.getText();
String value = (e == null ? null : e.toString());
if (TextUtils.isEmpty(value)) { //hat tip to Deepak Goyal's answer. Could also use isEmpty(e)
答案 1 :(得分:1)
你可以使用 TextUtils.isEmpty(值);
final EditText input = (EditText)view.findViewById(R.id.edit_text);
Button button = (Button)view.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String value = input.getText().toString();
if (TextUtils.isEmpty(value)) {
// value is empty
}else{
// have value
}
答案 2 :(得分:1)
您可能会收到此警告,因为value
不包含从EditText#getText()
返回的内容(返回CharSequence
),而是保留CharSequence#toString()
的回复(返回String
)。
对非空toString()
的{{1}}调用返回null应该是不可能的,这就是lint警告你不需要空检查的原因。您应该对CharSequence
的返回进行空检查。
换句话说,如果您的EditText#getText()
为空,那么在没有调用input.getText()
的情况下它就会失败,因此永远无法进行空检查。
答案 3 :(得分:0)
表达式
中的值String value = input.getText().toString();
不会是null
。
因为如果输入为null
,则它将为方法调用NPE
生成input.getText()
。因此下一个语句将不会执行。如果您处理此NPE
类似
String value = null;
if (input!=null) {
value = input.getText().toString();
}
if (value == null || value.length() == 0){
}
然后你就不会得到那个指示。