【发布时间】:2015-07-28 19:21:42
【问题描述】:
我正在编写一个我正在编写的 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 给我一个警告:
条件 'value == null' 始终为 false。
当我允许 Android Studio 为我“修复”问题时,它建议:
将 'value == null' 简化为 false
然后代码变成:
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;
}
TextView 的 setText() 方法似乎不允许 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() 似乎无法返回 null 值,但 this answer 上的 cmets 表明它是。 this question 的答案似乎也表明这是可能的。
我想练习防御性编码,这就是我从一开始就按照我的方式构建代码的原因,但我不想做null 检查不可能是null 的东西.那么,在这种情况下,最佳做法是什么?
【问题讨论】:
-
你会检查像 value.equals("") 并引用这个stackoverflow.com/a/3321548/4478125
-
我认为 lint 检查告诉您的信息与您从中读取的内容略有不同。对于这个 if 语句,
EditText.getText()是否可以返回 null 实际上并不重要。因为如果它返回 null,那么在到达 if 语句之前,.toString()将导致 NullPointerException。因此,如果 if 语句完全可以访问,则 value 不能为 null。因此,不需要value == null检查。 -
@Barend 那么这更有意义。我认为 lint 检查不够聪明,无法分析我所做的所有层。那么,问题就变成了我的
String value = input.getText().toString();行是否容易受到 NPE 的攻击。 -
如果你将
input.getText().toString()简化为null.toString(),你可以很容易地看到它会是NPE。我不确定getText()是否可以返回null,即使标准EditText不能,那么EditText的某些未知子类也可以,因此防御方法是将代码重写为完全null-安全的方式。 -
根据您通过挖掘源代码提供的详细信息,
getText不会返回 null。您在问题中发布的两个 SO 链接并没有真正说明 getText() 返回 null。