File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Java in General and the fly likes Type glitch caused by generics Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Type glitch caused by generics" Watch "Type glitch caused by generics" New topic
Author

Type glitch caused by generics

Michael Ka
Greenhorn

Joined: Jun 24, 2009
Posts: 4
Hi everyone,

I need some help from you, since I just can't tackle that problem regarding generics. I have the following method given by some API:



Now I'm implementing my own A that happens to have this structure:



It works just fine, if I invoke the operation like:



But since object Impl (or rather the constructors of Impl1, Impl2, ...) are somewhat complex, I want to hide them in a static factory method (and anyways only reveal what is needed outside, i.e. interface A):



A call to operation would look like this and work just fine:



But if I mix the "flavors" now (i.e. operation(Impl.flavorX(), Impl.flavorY());), eclipse yields the following error:

The method operation(A<? super T>, A<? super T>) in the type Test is not applicable for the arguments (A<Integer>, A<Double>)


Probably I miss a central characteristic of generics ... But why does it work with the concrete Impl1<T> class, but not with the interface A<T>? After working all day on that problem, I can't think straight anymore, when it comes to generics

Help is highly appreciated!

Thanks,
Michi
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19790
    
  20

Type inference sometimes does not work well when the result of a genericly typed method is directly used as the parameter of another method (or constructor).

You can solve this in (at least) two ways:
1) create temporary variables:

2) make the type explicit on the static method call:
This syntax of putting the generic type right before the method call will tell the compiler to use <T> as the generic type instead of trying to guess for itself.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Michael Ka
Greenhorn

Joined: Jun 24, 2009
Posts: 4
Thanks, Rob.

The following call still cases the same problem:



But I figured, a single constructor call added to the argument list, makes this problem go away:



That is very confusing. Does Java have problems inferring the types, even though I'm giving hints with .<T>? Also tried your first solution, but same result ...
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19790
    
  20

Michael Ka wrote:The following call still cases the same problem:


Well, that's kind of obvious. Your operation signature:

Now can you find a type T of which both Integer and Double are super types? I certainly can't. Don't you mean <? extends T>?
Michael Ka
Greenhorn

Joined: Jun 24, 2009
Posts: 4
Rob Prime wrote:Now can you find a type T of which both Integer and Double are super types?


True, I can not. And I guess my example works just because I'm ignoring the unchecked warning and generics are no subject to the runtime environment, right?

But I was being stupid. The operation() in the context above is Predicates#or(Predicate...) of Google collections. But on a collection of type, I'd never check for different types, anyways (like Predicates.or(Predicates.equalTo(new Date()), Predicates.equalTo(new String()));) because my collection is of a specific supertype.

Thanks again,
Mike
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19790
    
  20

Michael Ka wrote:Predicate.or(Predicate.equalTo(new Date()), Predicate.equalTo(new String()));

That could work though, if you ensure that the two calls to Predicate.equalTo return a Predicate<Object>.
Michael Ka
Greenhorn

Joined: Jun 24, 2009
Posts: 4
I deliberately chose the equalTo from Predicates to make a point because it returns actually Predicat<T> (unlike e.g. isNull which is in fact Predicate<Object>). So it's a no go and I have to be careful with usage of these composite methods ...
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19790
    
  20

But you can still make the method return a Predicate<Object>, and there are even two ways:
In the first example you're forcing T to be Object, and since a Date is an Object it won't complain. In the second example, you're passing Object as T so the result will also be Predicate<Object>.

But yes, these methods do not return Predicate<Object> out of their own. You'll have to force the compiler.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Type glitch caused by generics