9

I've just came across this interesting message from the compiler and I do not know why is it happening. Here is the case

Example 1.

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

Example 2.

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

In the first example, I need to cast an object returned by findViewById to Button. In the second example, I do not have to cast returned object because I did not use another Button class object. If I try to cast it via

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

I will get the warning Casting findViewById(R.id.someButtonId) to Button is redundant.

Why is this happening? I am not trying to remove cast warning. I want to know the logic behind this and why casting is not needed if I do not try to initialize another object with the object returned by findViewById.

sandalone
  • 41,141
  • 63
  • 222
  • 338

5 Answers5

7

The reason why you get this is because findViewById returns View and this class already defines the method setOnClickListener. This means that even without doing the cast you can set the listener. Thus your cast is redundant.

Boris Strandjev
  • 46,145
  • 15
  • 108
  • 135
  • To ask here as well: is it safe using it like in examp2? – sandalone Mar 01 '12 at 10:44
  • Why do you think it would not be safe? – devmiles.com Mar 01 '12 at 10:46
  • @VladimirVolodin I do not like working with parent objects like `View`. That's why I'm more comfortable when I work with explicit objects like in examp1. Am I over-concerned or wrongly-concerned? – sandalone Mar 01 '12 at 10:57
  • 1
    You are wrongly concerned in this case. It is perfectly fine to work with parent objects. I am totally sure you do not feel like doing something bad if you access a method of interface right. And still it is just the same case as accessing a method of parent class. After all it is always the case that you actually call the method of `Button`, just the calling "string" is different. – Boris Strandjev Mar 01 '12 at 11:02
  • 1
    @sandalone, you should familiarize yourself more with the programming concept of polymorphism - http://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html – devmiles.com Mar 01 '12 at 11:19
  • @BorisStrandjev: im learning Android in 2019, which seems that now even using `example 1`, you dont need to cast to `Button` object anymore? – Isaac May 10 '19 at 23:36
  • 1
    @Isaac Confirmed. Things change to the better :) Warm welcome to us Android devs :) – Boris Strandjev May 11 '19 at 06:08
2

The findViewById() always returns View which is parent of all Views such as ImageView, Button...

The setOnClickListener is a method of View class. So you can catch the click events simply without casting it to Button. I think so that only it says redundant.

Sadeshkumar Periyasamy
  • 4,848
  • 1
  • 26
  • 31
2

The reason for this is that in Example 1 you explicitly need to find a Button because you are assigning it to a Button variable.

The OnClickListener is for any type of View, so you do not need to cast it to a specific subclass of View to set an OnClickListener to it.

Eric Nordvik
  • 14,656
  • 8
  • 42
  • 50
1

It's happening because you don't need to cast View to Button in order to call setOnClickListener which is defined in View. It's enough to do findViewById(R.id.someButtonId).setOnClickListener(this);

devmiles.com
  • 9,895
  • 5
  • 31
  • 47
0

I'm guessing setOnClickListener() is a method in the View rather than the Button, and so yep: the cast is redundant.

John3136
  • 28,809
  • 4
  • 51
  • 69