Reputation: 212
It just seems like I'm declaring it's type twice, once in parentheses, once out of parentheses. Some examples of what I'm talking about:
HttpURLConnection my_urlConnection = (HttpURLConnection) url1.openConnection();
Button my_button = (Button) findViewById(R.id.btn1);
TextView my_textview = (TextView) findViewById(R.id.textview1);
What does it mean?
Upvotes: 2
Views: 1141
Reputation: 1073978
openConnection
's return type is URLConnection
, not HttpURLConnection
, but if you know that the type of URL you're opening is an HTTP URL, you know that you're getting back an HttpURLConnection
(a subclass of URLConnection
).
Similarly, the return type of findViewById
is View
, but if you know you're looking up a Button
, or a TextView
, you know you're getting back a Button
or TextView
(subclasses of View
), not just a raw View
.
So the type names are there to cast the return values to the expected concrete types: You're saying "I know that the actual object is at least of this subtype, not just of that supertype, so change my reference to it to use the subtype." This is so you have access to the features provided by those subtypes, rather than being limited to accessing the common features of the base types. (If "casting" is an unfamilar term, see this tutorial's section "Casting Objects".)
Of course, if you're mistaken that what you get back will actually be one of those subclasses, you'll get a ClassCastException
.
This isn't specific to Android development, it's a general concept common to several programming languages. It's like the Bad Old Days when we didn't have generics, and so every time you retrieved something from a Map
, you had to cast it to what you knew it was, because the return type of get
was Object
:
Map map = new HashMap();
// ...later...
Thingy t = (Thingy)map.get("myThingy");
Nowadays, we can say "This map has Thingy
instances in it" like this, and not have to do that — a parameterized Map
's get
method returns a reference typed appropriately:
Map<String, Thingy> map = new HashMap<String, Thingy>();
// ...later...
Thingy t = map.get("myThingy");
But that's not being used in the code you quoted, because either the APIs don't support it, or it's just legacy code from before generics.
Upvotes: 1
Reputation: 13730
It's a cast. The type in parentheses basically tells the compiler "attempt to treat whatever comes after this as this type". This is often necessary because the return type of the method is of a parent class and you need a subclass.
For example, in your second line of code, you write:
Button my_button = (Button) findViewById(R.id.btn1);
findViewById
doesn't return a Button
. It returns a View
. Even though the view it returns might actually be a Button
, it doesn't know that for sure. It's a dumb method that only knows about View
s. So you need to tell Java "assume this is a button and cast it to the appropriate type". If you instead did this...
View my_view = findViewById(R.id.btn1);
...you wouldn't need a cast. You don't need to write (View)findViewById(R.id.btn1);
, because the return type of the method and the type of the variable you're assigning it to both match. You also don't need to cast if you're assigning a subclass to a parent class. This is legal without a cast:
View my_view = new Button(); // No cast necessary. Button is a subclass of View and can be used anywhere View is used.
This is not legal:
Button my_button = new View(); // View can't be automatically converted to Button unless it was a Button to begin with.
Also note that you can't use casts to convert any type to any other type. You can only cast an object to a type if it is that type, or is a parent class or subclass of that type. Example:
try {
View my_view = (View)(new Activity());
}
catch(ClassCastException e)
{
// This will always happen. Activity isn't a parent or subclass of View.
}
There's a tutorial here that might help you.
Upvotes: 6
Reputation: 198014
It's a cast to that type, just like it is in normal Java.
Upvotes: 4