| Author |
Not understanding the use of Parameterized return types
|
James Gary
Greenhorn
Joined: Mar 17, 2010
Posts: 9
|
|
Fairly new to Generics, and despite my best effort, I can't figure out what it is I'm missing.
I've defined the following class that compiles without error (ancillary code omitted):
Why is it that in client code, I can never get past a compiler error on the variable declaration "ConversionElement e" when I try to do this with an instance of DataMap?
The compiler error is "Incompatible Types, Required ConversionElement, Found Object." Why does the compiler think that ConversionElements() returns a Collection of Object instead of a Collection of ConversionElement, and forces me to do this?
|
 |
Mike Simmons
Ranch Hand
Joined: Mar 05, 2008
Posts: 1941
|
|
|
Where is the variable dataMap declared? Not the class DataMap, but the variable dataMap. It doesn't seem to be shown above, and I'm pretty sure that's where the problem lies.
|
 |
Mike Simmons
Ranch Hand
Joined: Mar 05, 2008
Posts: 1941
|
|
Oh, also there's a fairly well-established convention in Java that method names and variable names should begin with lowercase, while class and interface names begin in uppercase. Violating this tends to cause unnecessary confusion in your readers, and possibly irritation with or disrespect for the author of the code. So the method ConversionElements() should probably be conversionElements(). Unless you're deliberately trying to mess with people's expectations.
|
 |
salvin francis
Ranch Hand
Joined: Jan 12, 2009
Posts: 900
|
|
Mike Simmons wrote:Unless you're deliberately trying to mess with people's expectations. 
Go easy friend its his first post
Welcome to javaranch James Gary
You can edit your post any time using the edit button...
|
I came, I saw, I set a new standard.
[Salvin.in]- The way websites should now be.
|
 |
Rob Spoor
Saloon Keeper
Joined: Oct 27, 2005
Posts: 17259
|
|
What you must understand is that the for-each loop is a syntactical shortcut for the following:
Now in your example Type is actually unknown. Type inference only works if the left hand side specifies what the type should be. But because this Iterator's declaration is automatically generated, there is no code that says what Type should be except one line of code two lines later. The compiler isn't going to accept that.
I see three options:
1) write your loop as above
2) get a variable for your collection first:
Type inference is now possible because you actually specify what V should be.
3) explicitly declare the type in the method call:
This way you manually specify what V should be.
|
SCJP 1.4 - SCJP 6 - SCWCD 5
How To Ask Questions How To Answer Questions
|
 |
Mike Simmons
Ranch Hand
Joined: Mar 05, 2008
Posts: 1941
|
|
Or, of course, you could specify V when you declare the type of dataMap. Your code is behaving as if you've written
But what you need is
Or replace ConversionElement with some other specific subtype if that's preferable. The problem is that if you omit the generic type entirely, the compiler
does not do the reasonable thing and infer that V must at least be a ConversionElement. Instead, it uses erasure, which basically means all generic type information is lost, and V is replaced with Object - hence the compiler error you observed.
|
 |
Rob Spoor
Saloon Keeper
Joined: Oct 27, 2005
Posts: 17259
|
|
Mike Simmons wrote:Or, of course, you could specify V when you declare the type of dataMap. Your code is behaving as if you've written
But what you need is
You know, I think you got it. I misread the V in the opening post as a method-generic type, but it belongs to the entire class. Which indeed means that dataMap is declared without generics.
|
 |
James Gary
Greenhorn
Joined: Mar 17, 2010
Posts: 9
|
|
Mike Simmons wrote:Where is the variable dataMap declared? Not the class DataMap, but the variable dataMap. It doesn't seem to be shown above, and I'm pretty sure that's where the problem lies.
Mike, you're correct. I didn't include the declaration, but see that that is certainly where the problem lies. Following up after I clean up my original post...
|
 |
James Gary
Greenhorn
Joined: Mar 17, 2010
Posts: 9
|
|
salvin francis wrote:
Mike Simmons wrote:Unless you're deliberately trying to mess with people's expectations. 
Go easy friend its his first post
Welcome to javaranch James Gary
You can edit your post any time using the edit button...
Thanks for watching the newbie's back
No offense taken with Mike's post.
Now looking for the "edit" button...
|
 |
James Gary
Greenhorn
Joined: Mar 17, 2010
Posts: 9
|
|
Mike Simmons wrote:Oh, also there's a fairly well-established convention in Java that method names and variable names should begin with lowercase, while class and interface names begin in uppercase. Violating this tends to cause unnecessary confusion in your readers, and possibly irritation with or disrespect for the author of the code. So the method ConversionElements() should probably be conversionElements(). Unless you're deliberately trying to mess with people's expectations. 
I agree and use this convention. Figures my first post to a java forum breaks convention and I didn't see it. Thanks.
|
 |
James Gary
Greenhorn
Joined: Mar 17, 2010
Posts: 9
|
|
Mike Simmons wrote:Or, of course, you could specify V when you declare the type of dataMap. Your code is behaving as if you've written
But what you need is
Or replace ConversionElement with some other specific subtype if that's preferable. The problem is that if you omit the generic type entirely, the compiler
does not do the reasonable thing and infer that V must at least be a ConversionElement. Instead, it uses erasure, which basically means all generic type information is lost, and V is replaced with Object - hence the compiler error you observed.
Thanks for the help. It should have been obvious to me after typing ArrayList<Type> dozens of times.
Corrected, working code follows:
|
 |
James Gary
Greenhorn
Joined: Mar 17, 2010
Posts: 9
|
|
I missed the opportunity to edit the original post, so I am copying here to provide clarity...
Why is it that in client code, I can never get past a compiler error on the variable declaration "ConversionElement e" when I try to do this with an instance of DataMap?
The compiler error is "Incompatible Types, Required ConversionElement, Found Object." Why does the compiler think that ConversionElements() returns a Collection of Object instead of a Collection of ConversionElement, and forces me to do this?
|
 |
Rob Spoor
Saloon Keeper
Joined: Oct 27, 2005
Posts: 17259
|
|
|
Because when you declare your variable as "DataMap dataMap", all generic information is lost. conversionElements() now no longer returns Collection<V> but Collection - no generic type there. Not even ConversionElement, the root of the allowed generic types. And you can only retrieve elements as Object from any raw collection.
|
 |
James Gary
Greenhorn
Joined: Mar 17, 2010
Posts: 9
|
|
Rob Prime wrote:Because when you declare your variable as "DataMap dataMap", all generic information is lost. conversionElements() now no longer returns Collection<V> but Collection - no generic type there. Not even ConversionElement, the root of the allowed generic types. And you can only retrieve elements as Object from any raw collection.
Thanks Rob.
|
 |
James Gary
Greenhorn
Joined: Mar 17, 2010
Posts: 9
|
|
salvin francis wrote:
Mike Simmons wrote:Unless you're deliberately trying to mess with people's expectations. 
Go easy friend its his first post
Welcome to javaranch James Gary
You can edit your post any time using the edit button...
Bummer, they apparently have a time limit here for which you can edit your original post.
http://faq.javaranch.com/java/JavaRanchFaq
|
 |
 |
|
|
subject: Not understanding the use of Parameterized return types
|
|
|