• Post Reply Bookmark Topic Watch Topic
  • New Topic

Generic / wildcard question  RSS feed

 
Raf Szczypiorski
Ranch Hand
Posts: 383
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi. I have the code:

Line 16 fails compilation, with the compiler saying (Eclipse 3.5, but javac issues similar message, with the capture numbers randomized):
"The method m(C<capture#2-of ?>) in the type F<capture#2-of ?> is not applicable for the arguments (C<capture#3-of ?>)"

I do understand why this fails - after all, all the compiler knows is that c and f are parametrized with _any_ type, and it doesn't know if they are compatible. The question is: how can I make this compile (and explanation why) except for using raw types.

Best regards,
szczyp
 
John Storta Jr.
Greenhorn
Posts: 29
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Try this.



You are declaring both C and F with parameter types of <T>. While it might seem like the parameters are the same, it is completely different for each class. When you specify C<T> in your code on line 6, the compiler tries to apply the <T> type parameter for the F class. The message you are getting indicates that you cannot apply that type to the C object because they are two completely different things. It does not matter that you set both C and F to <Object> when you initialize them.

The solution is that you do not need to specify any type parameter in the method argument list. To the m method, it is just needs a C object. The specifics of what is in that object are irrelevant to the m method. You take care of defining the type parameter for the C object when you initialize it on line 14. If you do not specify it there, then it will not compile.


 
Raf Szczypiorski
Ranch Hand
Posts: 383
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi. Thank you for your answer.
If you read my post carefully, though, I mentioned that I know how to make it compile using raw types, which is what you do. The type declarations C and F are raw declarations.

Refards,
szczyp
 
Rob Spoor
Sheriff
Posts: 21135
87
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Raf Szczypiorski wrote:

Although c is a C<Object> and f is an F<Object>, the compiler forgets this information immediately because you declared both using a wild card. The compiler doesn't know anymore if c is a C<Object>, a C<Integer>, a C<String>, etc. The only way to make this work is to not throw away this information:
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Raf Szczypiorski wrote:
I do understand why this fails - after all, all the compiler knows is that c and f are parametrized with _any_ type, and it doesn't know if they are compatible. The question is: how can I make this compile (and explanation why) except for using raw types.


Wildcards do not mean "any type" -- it means that the type is unknown. And since both of your references are types that are unknown, there is no way to confirm that the type using by F is the same as C. If you declared the type as Object, for both, then it should work.

[EDIT: beaten to the answer again... ]

Henry
 
Raf Szczypiorski
Ranch Hand
Posts: 383
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

yes, my wording was incorrect, but I do understand that the types are unknown. (not any, as said before). Thanks for the correction.
Yes, the <Object> stuff works, but the thing is I need to have it working with wildcards. I have an API (programmatic lookups of beans using CDI's BeanManager) that returns wildcarded types, and after a specific sequence of calls the problem bites me. I am starting to think I have to use raw types.

Regards,
szczyp
 
Rob Spoor
Sheriff
Posts: 21135
87
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If your methods return types have unbounded wildcards (?) then you have to cast or use raw types. Both will produce a warning, because both are potentially dangerous - you are shutting off / bypassing any generic type checking by the compiler.

Is it not possible to have bounded wildcards? For example:
You still need to specify one of the with its full type (or maybe bounding using super) but you get a bit more freedom.
 
kri shan
Ranch Hand
Posts: 1489
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When you use wildcards with Generics compiler will give warning messages. Don't ignore those warning messages. It may lead to runtime issue like ClassCastException.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!