Как работает эта версия findViewById()?

Эта версия View.findViewById() возвращает наиболее конкретный конкретный подтип View:

protected <T extends View> T findViewById(@IdRes int id) {
    return (T) getRootView().findViewById(id);
}

Как это работает? В частности, как определить тип во время компиляции, когда id просматривается во время выполнения? Это связано с аннотацией?

Это отличается от вопросов с похожими названиями, которые касаются использования findViewById():

Я хотел бы знать, почему это работает.


person Ellen Spertus    schedule 26.02.2019    source источник
comment
findViewById() возвращает объект просмотра. Затем этот Object преобразуется в то, что определено как T. Это то, что вы имели ввиду?   -  person TheWanderer    schedule 27.02.2019


Ответы (1)


Это не может быть выведено. Он использует приведение - return (T). Вызывающий объект отвечает за то, чтобы тип T соответствовал типу находящегося представления. Если они ошибутся, операция завершится с ошибкой ClassCastException.

Тип может быть указан явно, т.е.

this.<TextView>findViewById(R.id.someTextView)

(извините за синтаксис, если я ошибаюсь - сейчас я в основном работаю с Котлином)

или это можно вывести из пункта назначения:

TextView foundView = findViewById(R.id.someTextView)

но в любом случае ответственность лежит на вызывающем абоненте.

Инструментальная цепочка Android может выполнить дополнительную работу по перекрестным ссылкам макета XML с кодом и выдать предупреждения или сбои в вашей среде IDE, но это уровень времени компиляции поверх того, что Java выполняет во время выполнения.

Это не имеет ничего общего с аннотацией @IdRes, которая должна утверждать - опять же во время компиляции - что параметр id является ссылкой на идентификатор некоторого объекта на основе XML, а не просто какое-либо целочисленное значение.

person Rob Pridham    schedule 26.02.2019
comment
Благодарю вас! Чего мне не хватало, так это того, что его можно было вывести из пункта назначения. - person Ellen Spertus; 27.02.2019