来自 EditText 的 getText():是否有可能获得 'null'?
getText() from EditText: is it possible to get a 'null'?
我正在研究我正在编写的 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 给我一个警告:
Condition 'value == null' is always false.
当我允许 Android Studio 为我 "fix" 解决问题时,它建议:
Simplify 'value == null' to false
代码则变为:
if (value.length() == 0) {
我查看了 Android 源代码 (http://www.grepcode.com),但我很困惑。 EditText
的文档说 "EditText is a thin veneer over TextView that configures itself to be editable." 然后, getText()
方法定义如下:
@Override
public Editable getText() {
return (Editable) super.getText();
}
当我去 getText()
寻找 TextView
("super")时,我看到了这个:
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()
没有办法 return 一个 null
值,但是 this answer indicate that it is. The answers to this question 上的评论似乎也表明它有可能。
我想练习防御性编码,这就是为什么我从一开始就按照我的方式构建我的代码,但我不想做 null
检查一些不可能的事情成为 null
。那么,在这种情况下,最佳做法是什么?
你可以使用
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
}
您可能会收到此警告,因为您的 value
不包含从 EditText#getText()
return 编辑的内容(return 是 CharSequence
),它取而代之的是 CharSequence#toString()
中的 return(return 是 String
)。
toString()
调用非空 CharSequence
到 return 空应该是不可能的,这就是为什么 lint 警告您不需要空检查的原因。您应该改为对 EditText#getText()
的 return 进行空值检查。
换句话说,如果您的 input.getText()
为 null,则它在未调用 toString()
之前就已经失败,因此您的 null 检查将永远无法进行。
我认为 lint 检查告诉您的信息略有不同:
String value = input.getText().toString();
if (value == null || value.length() == 0) {
Condition 'value == null' is always false.
实际上,在这个 if 语句中,EditText.getText()
是否可以 return null 并不重要。因为如果它 return 为 null,那么 .toString()
甚至会在到达 if 语句之前引发 NullPointerException。因此,如果 if 语句完全可达,则值不能为空。
你可以翻遍 Android 源代码,也许你会发现 EditText
到 return 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)
表达式中的值
String value = input.getText().toString();
不会是null
。
因为如果输入是 null
,它将为方法调用 input.getText()
生成一个 NPE
。因此下一条语句不会执行。如果你处理这个 NPE
类似
的东西
String value = null;
if (input!=null) {
value = input.getText().toString();
}
if (value == null || value.length() == 0){
}
那么你将不会得到那个指示。
我正在研究我正在编写的 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 给我一个警告:
Condition 'value == null' is always false.
当我允许 Android Studio 为我 "fix" 解决问题时,它建议:
Simplify 'value == null' to false
代码则变为:
if (value.length() == 0) {
我查看了 Android 源代码 (http://www.grepcode.com),但我很困惑。 EditText
的文档说 "EditText is a thin veneer over TextView that configures itself to be editable." 然后, getText()
方法定义如下:
@Override
public Editable getText() {
return (Editable) super.getText();
}
当我去 getText()
寻找 TextView
("super")时,我看到了这个:
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()
没有办法 return 一个 null
值,但是 this answer indicate that it is. The answers to this question 上的评论似乎也表明它有可能。
我想练习防御性编码,这就是为什么我从一开始就按照我的方式构建我的代码,但我不想做 null
检查一些不可能的事情成为 null
。那么,在这种情况下,最佳做法是什么?
你可以使用 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
}
您可能会收到此警告,因为您的 value
不包含从 EditText#getText()
return 编辑的内容(return 是 CharSequence
),它取而代之的是 CharSequence#toString()
中的 return(return 是 String
)。
toString()
调用非空 CharSequence
到 return 空应该是不可能的,这就是为什么 lint 警告您不需要空检查的原因。您应该改为对 EditText#getText()
的 return 进行空值检查。
换句话说,如果您的 input.getText()
为 null,则它在未调用 toString()
之前就已经失败,因此您的 null 检查将永远无法进行。
我认为 lint 检查告诉您的信息略有不同:
String value = input.getText().toString();
if (value == null || value.length() == 0) {
Condition 'value == null' is always false.
实际上,在这个 if 语句中,EditText.getText()
是否可以 return null 并不重要。因为如果它 return 为 null,那么 .toString()
甚至会在到达 if 语句之前引发 NullPointerException。因此,如果 if 语句完全可达,则值不能为空。
你可以翻遍 Android 源代码,也许你会发现 EditText
到 return 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)
表达式中的值
String value = input.getText().toString();
不会是null
。
因为如果输入是 null
,它将为方法调用 input.getText()
生成一个 NPE
。因此下一条语句不会执行。如果你处理这个 NPE
类似
String value = null;
if (input!=null) {
value = input.getText().toString();
}
if (value == null || value.length() == 0){
}
那么你将不会得到那个指示。