EditText.java代码中的此注释是什么意思?

时间:2018-11-14 02:20:30

标签: java android android-edittext

我已经浏览了EditText.java的第109行,下面的注释可以在 getText()方法:

// This can only happen during construction.

它的目的是什么?

谢谢

2 个答案:

答案 0 :(得分:2)

我将扩展针对这组特定课程的安德里亚斯的答案。

EditTextTextView的子类。这就是为什么将其声明为:

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;
}

是的,mTextsetTextInternal()在TextView构造期间修改的引用/实例相同。

这就是为什么在构建期间(在调用setTextInternal("")之前,字段mText(您通过getText()访问)可以为空的原因,但是不会。

¯\_(ツ)_/¯

老实说,我什至不知道他们为什么这样做,而且评论似乎有点愚蠢,但是正如您可能已经猜到的那样,这些类是数千行代码,人们倾向于相信成为这个原因的理由最好的办法就是开始分析整个TextView类。祝你好运。 :)

答案 1 :(得分:1)

该评论的目的是告诉所有认为下一条语句是多余的程序员,即text永远不可能是null,因为它们可以EditText对象的构造过程中发生,因此请不要删除该语句。