• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Tim Cooke
  • Jeanne Boyarsky
  • Liutauras Vilda
Sheriffs:
  • Frank Carver
  • Henry Wong
  • Ron McLeod
Saloon Keepers:
  • Tim Moores
  • Frits Walraven
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
Bartenders:
  • Al Hobbs
  • Piet Souris
  • Himai Minh

generics and class literals

 
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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);
 
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 ]
 
author and iconoclast
Posts: 24204
44
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Wow!

OK, can you now explain why this works?
 
Jim Yingst
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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...
 
No holds barred. And no bars holed. Except this tiny ad:
the value of filler advertising in 2021
https://coderanch.com/t/730886/filler-advertising
reply
    Bookmark Topic Watch Topic
  • New Topic