• Post Reply Bookmark Topic Watch Topic
  • New Topic

Generic Type Mismatch  RSS feed

 
Adam Richards
Ranch Hand
Posts: 135
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a class defined as follows:

public class MultiFacilitySearchDataProvider <T extends Facility & MilepostValue & Copyable<T>>

The class has this method:

protected T getFacility(final FacilityInstance instance) {

final MultiFacilitySearchDAO dao = new MultiFacilitySearchDAO(instance);
ENM.execute(dao);
return dao.getResultModel(); // Compile error here

}

The DAO method called above looks like this:

public MultiFacilitySearchModel getResultModel() {
return resultModel;
}

And MultiFacilitySearchModel is defined as follows:

public class MultiFacilitySearchModel implements Copyable<MultiFacilitySearchModel>, Facility,
Serializable, MilepostValue, MenuDisplayValues

The problem is that the line return dao.getResultModel() generates a compile error "Type mismatch: cannot convert from MultiFacilitySearchModel to T". I don't understand why I'm getting this error, since MultiFacilitySearchModel implements the three interfaces specified for the generic type T. What am I missing?
 
Paul Clapham
Sheriff
Posts: 22823
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm kind of lost by all those similar-sounding class names. But anyway, somewhere you should be declaring a variable whose type is MultiFacilitySearchDataProvider<Something>. Could you post that line of code?
 
Adam Richards
Ranch Hand
Posts: 135
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, I do use it elsewhere:

public MultiFacilityListPanel(final String id, final EnmPage parent,
final FacilitySearchByLocationCriteria criteria) {
super(id, parent, new MultiFacilitySearchDataProvider(criteria), criteria.getSearchType());
}

But this snippet isn't finished yet, because the data provider class won't compile (yet)
 
Matthew Brown
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
MultiFacilitySearchModel implements all three interfaces for a particular value of T. But the compiler has no way of knowing whether it's compatible with every possible value of T.

So it knows the following:

- getResultModel() returns a MultiFacilitySearchModel
- This is-a Facility, MilepostValue, and Copyable<MultiFacilitySearchModel>
- But it needs to be a T, and all we know about T is that it is also a Facility, MilepostValue, and Copyable<T>

Let's say I create a new class:

Now I create a MultiFacilitySearchDataProvider<IncompatibleSearchModel>. That cast won't work.

 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Adam Richards wrote:The problem is that the line return dao.getResultModel() generates a compile error "Type mismatch: cannot convert from MultiFacilitySearchModel to T". I don't understand why I'm getting this error, since MultiFacilitySearchModel implements the three interfaces specified for the generic type T.

No it doesn't, unless it also includes a T in its definition (which, on the surface, would seem kind of pointless; and which doesn't appear to be the case anyway).

What am I missing?

An English explanation of exactly what you're trying to achieve.

One thing that's probably worth remembering about generics is that it's a kludge - albeit a pretty good one - to mask the fact that compile-time type checking wasn't really properly implemented in Java from the outset. And for that reason there are some things that it just can't do.

Even constructs as "simple" as:
public interface MyInterface<T, C extends MyInterface<T, C>>
(which I notice is sprouting up a lot in version 8 as a form of "factoried" return type) have to be used with caution.

And for that reason, the general rule is "keep it simple". If I can't read your class definition and understand immediately what's going on, the chances are you're going to run into problems down the line.

Generics, IMO, is an "80/20" solution. It does the basics well for very little effort, but it can't do everything; and the more you try to make it a "compiler for the compiler", the more problems you're likely to run into.

My 2¢.

Winston
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:One thing that's probably worth remembering about generics is that it's a kludge - albeit a pretty good one...

And just to add to my previous post: One of the reasons it's "good" is that I've generally found that when I do start overthinking things and run into problems, it's almost always because my design is wrong, and there's a much simpler (and equally effective) solution available.

Not always; but mostly. And in your case I'm not yet sure what that is; which is why that "English" explanation would really help.

Winston
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!