我已经浏览了EditText.java的第109行,下面的注释可以在
getText()
方法:
// This can only happen during construction.
它的目的是什么?
谢谢
答案 0 :(得分:2)
我将扩展针对这组特定课程的安德里亚斯的答案。
EditText
是TextView
的子类。这就是为什么将其声明为:
class EditText extends TextView
(简体...)
EditText构造函数如下所示:
public EditText(Context context) {
this(context, null);
}
public EditText(Context context, AttributeSet attrs) {
this(context, attrs, com.android.internal.R.attr.editTextStyle);
}
public EditText(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public EditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
注意每个构造函数如何调用另一个,直到最后一个(长整数)为止。
这个很棘手,因为它调用super(…)
意味着现在正在调用超类的构造函数(TextView
)。
EditText只是一个专门的TextView,我们可以从中推断出这一点; TextView还声明了一个名为text
的变量,EditText当然也使用该变量。当您向EditText索要text
时,它仅使用TextView已经拥有并发现的代码:
@Override
public Editable getText() {
CharSequence text = super.getText();
// This can only happen during construction.
if (text == null) {
return null;
}
[rest of code removed for clarity]
}
因此,它向其super
(TextView)请求text
;为什么此文本可以为空?要回答这个问题,您需要查看TextView
本身(https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/widget/TextView.java)。
稍后大约有1000行代码……TextView声明了其构造函数;为了简单起见,我将其粘贴,但是它们非常简单:
public TextView(Context context) {
this(context, null);
}
请注意,它们再次 调用this(…)
和 chain 构造……一个构造函数调用另一个,依此类推……直到到达TextView的最后一个大构造……
@SuppressWarnings("deprecation")
public TextView(
Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
// TextView is important by default, unless app developer overrode attribute.
if (getImportantForAutofill() == IMPORTANT_FOR_AUTOFILL_AUTO) {
setImportantForAutofill(IMPORTANT_FOR_AUTOFILL_YES);
}
setTextInternal("");
[rest of code removed for clarity]
请注意,此构造函数调用setTextInternal("")
,看起来很可疑!会在构造时将文本设置为空字符串,因此TextView
在此构造函数完成后具有null文本将是不可能(您可以使用反射…但是我们不要去那里);由于EditText
构造函数被链接起来并最终总是调用TextView
构造函数,因此该方法setTextInternal("")
被保证在某些情况下被调用 Java中对象构建期间的指向。 (这就是构造函数,这是一个Java合同,如果不可靠,它将破坏世界的1/2!)。
此方法有什么作用?
很明显,一堆内部事物……
// Update mText and mPrecomputed
private void setTextInternal(@Nullable CharSequence text) {
mText = text; // #### THIS IS WHERE IT SETS THE TEXT TO NON NULL ("").
mSpannable = (text instanceof Spannable) ? (Spannable) text : null;
mPrecomputed = (text instanceof PrecomputedText) ? (PrecomputedText) text : null;
}
如果您还记得EditText#getText()
叫super.getText()
的话,请猜猜超级超级什么样? (TextView
):
public CharSequence getText() {
return mText;
}
是的,mText
与setTextInternal()
在TextView构造期间修改的引用/实例相同。
这就是为什么在构建期间(在调用setTextInternal("")
之前,字段mText
(您通过getText()
访问)可以为空的原因,但是不会。
¯\_(ツ)_/¯
老实说,我什至不知道他们为什么这样做,而且评论似乎有点愚蠢,但是正如您可能已经猜到的那样,这些类是数千行代码,人们倾向于相信成为这个原因的理由最好的办法就是开始分析整个TextView类。祝你好运。 :)
答案 1 :(得分:1)
该评论的目的是告诉所有认为下一条语句是多余的程序员,即text
永远不可能是null
,因为它们可以 在EditText
对象的构造过程中发生,因此请不要删除该语句。