Приведение к кнопке избыточно — почему?

Я только что наткнулся на это интересное сообщение от компилятора, и я не знаю, почему это происходит. Вот случай

Пример 1.

Button test = (Button) findViewById(R.id.someButtonId);
test.setOnClickListener(this);

Пример 2.

findViewById(R.id.someButtonId).setOnClickListener(this);

В первом примере мне нужно преобразовать объект, возвращенный findViewById, в Button. Во втором примере мне не нужно приводить возвращаемый объект, потому что я не использовал другой объект класса Button. Если я попытаюсь передать его через

((Button)findViewById(R.id.someButtonId)).setOnClickListener(this);

Я получу предупреждение Casting findViewById(R.id.someButtonId) to Button is redundant.

Почему это происходит? Я не пытаюсь удалить предупреждение о приведении. Я хочу знать логику, стоящую за этим, и почему приведение не требуется, если я не пытаюсь инициализировать другой объект с помощью объекта, возвращаемого findViewById.


person sandalone    schedule 01.03.2012    source источник
comment
stackoverflow.com/questions/3502690/   -  person Samir Mangroliya    schedule 01.03.2012
comment
@ Самир, я знаю, как это удалить :). Мне это не нужно. Я спрашиваю, почему кастинг не нужен.   -  person sandalone    schedule 01.03.2012
comment
:( я не получаю предупреждение   -  person Triode    schedule 01.03.2012
comment
@rajesh.adhi Используйте IntelliJ IDEA, и вы это сделаете. Лучшее средство! ;)   -  person sandalone    schedule 01.03.2012
comment
:O я использую Eclipse, все равно спасибо   -  person Triode    schedule 01.03.2012


Ответы (5)


Причина, по которой вы получаете это, заключается в том, что findViewById возвращает View, а этот класс уже определяет метод setOnClickListener. Это означает, что даже не выполняя приведение, вы можете установить слушателя. Таким образом, ваш актерский состав лишний.

person Boris Strandjev    schedule 01.03.2012
comment
Чтобы спросить и здесь: безопасно ли использовать его, как в примере 2? - person sandalone; 01.03.2012
comment
Почему вы думаете, что это небезопасно? - person devmiles.com; 01.03.2012
comment
@VladimirVolodin Мне не нравится работать с родительскими объектами, такими как View. Вот почему мне удобнее работать с явными объектами, как в примере1. Я слишком озабочен или неправильно обеспокоен? - person sandalone; 01.03.2012
comment
Вы напрасно обеспокоены в данном случае. Совершенно нормально работать с родительскими объектами. Я полностью уверен, что вам не захочется делать что-то плохое, если вы правильно получите доступ к методу интерфейса. И все равно это тот же случай, что и обращение к методу родительского класса. В конце концов, всегда бывает так, что вы на самом деле вызываете метод Button, просто вызывающая строка отличается. - person Boris Strandjev; 01.03.2012
comment
@sandalone, вам следует больше ознакомиться с концепцией полиморфизма в программировании - docs .oracle.com/javase/tutorial/java/IandI/polymorphism.html - person devmiles.com; 01.03.2012
comment
@BorisStrandjev: я изучаю Android в 2019 году, и кажется, что теперь, даже используя example 1, вам больше не нужно приводить к объекту Button? - person Isaac; 11.05.2019
comment
@ Исаак Подтверждено. Все меняется к лучшему :) Добро пожаловать к нам, разработчикам Android :) - person Boris Strandjev; 11.05.2019

findViewById() всегда возвращает представление, которое является родительским для всех представлений, таких как ImageView, Button...

setOnClickListener — это метод класса View. Таким образом, вы можете перехватывать события кликов, просто не приводя их к кнопке. Я так думаю, что только это говорит избыточно.

person Sadeshkumar Periyasamy    schedule 01.03.2012

Причина этого в том, что в примере 1 вам явно нужно найти кнопку, потому что вы присваиваете ее переменной Button.

OnClickListener предназначен для любого типа представления, поэтому вам не нужно приводить его к определенному подклассу представления, чтобы установить для него OnClickListener.

person Eric Nordvik    schedule 01.03.2012
comment
Абсолютно. Какое бы представление ни находилось в примере 2, для него можно установить OnClickListener. - person Eric Nordvik; 01.03.2012
comment
Вы в любом случае будете точно знать, что это кнопка, потому что вы не используете идентификатор someButtonId для каких-либо других представлений, не так ли? - person Eric Nordvik; 01.03.2012

Это происходит потому, что вам не нужно преобразовывать View в Button, чтобы вызвать setOnClickListener, который определен в View. Достаточно сделать findViewById(R.id.someButtonId).setOnClickListener(this);

person devmiles.com    schedule 01.03.2012

Я предполагаю, что setOnClickListener() - это метод в представлении, а не в кнопке, и поэтому да: приведение избыточно.

person John3136    schedule 01.03.2012