wood burning stoves 2.0*
The moose likes Java in General and the fly likes generics and class literals Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "generics and class literals" Watch "generics and class literals" New topic
Author

generics and class literals

Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
How do I call the method

public static void foo(Class<? extends List<? extends CharSequence>> clazz)

using a class literal? Neither of the following lines compiles:

foo(List<String>.class);
foo(List.class);
foo((Class<List<String>> List.class);


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Anonymous
Ranch Hand

Joined: Nov 22, 2008
Posts: 18944
Hi Ilja,

There is no way of doing that with generics due to type erasure. When parametrized types are compiled, the compiler translates these types into bytecode.

See this article on type erasure for more details.

Cheers
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
foo((Class) List.class);

This gives me a warning in my IDE (IntelliJ), but it does compile and run correctly. And the warnings can be dealt with by judicious use of @SuppressWarnings. This is a case where erasure can be made to work for you.

This example would suggest that it was a mistake to give the foo() method such a specific signature - though it's hard to tell exactly at what point did it become too complex. Seems like there's an extra layer of unanticipated complications the moment generic types are nested - i.e. angle braces within angle braces. That may not be a well-justified formal rule, but so far it seems like a good guideline to me: avoid nesting angle braces in generic types. Unless you really need them...
[ May 03, 2006: Message edited by: Jim Yingst ]

"I'm not back." - Bill Harding, Twister
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24183
    
  34

Wow!

OK, can you now explain why this works?


[Jess in Action][AskingGoodQuestions]
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Oops! Revisiting this, it looks like I screwed up and found a solution to a modified version of the problem. This doesn't work for the original problem. Nevermind.

Will have to see if there is any other way to do this. Looks doubtful though...
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Well, here are two solutions, though I imagine neither is really what was desired:

or

Of course the latter is more useful if you want to be able to do anything with the Class parameter wiithin foo().
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Ah, solution came to me over lunch.:

The (Object) gets the compiler to ignore what it thinks it knows about the type at compile time, then let you fib about what type it is with a much more specific cast. At run time, it's equivalent to the erasure:

Of course the (Object) cast may be dropped by now. (Probably already was.)

Moral: Food good. Eat more.
[ May 03, 2006: Message edited by: Jim Yingst ]
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Jim Yingst:
Ah, solution came to me over lunch.:



Ouch. I don't think we want to use that...

My coworkers have found another solution: subclassing. If you have a class

class StringList extends ArrayList<String>

StringList.class works like a charm. (Our actual code was a little bit more complex, so subclassing proved to simplify the code, anyway.)

Moral: Food good. Eat more.


You're ruining my diet plan!
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Jim Yingst:
That may not be a well-justified formal rule, but so far it seems like a good guideline to me: avoid nesting angle braces in generic types. Unless you really need them...


They are certainly not unproblematic, but you can also do very cool things with it.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Jim Yingst:
Ah, solution came to me over lunch.:



We just found out that it suffices to cast to a raw Class:

foo((Class<? extends List<? extends CharSequence>> (Class) List.class);

Makes *kind* of sense, I guess...
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: generics and class literals
 
Similar Threads
doubt - generics in method ...
Is this a bug?
Generic method
Collections.sort and generics
? extends String