Ah, I forgot the context around which we were discussing Foo.class. That is definitely a shortcoming of erasure if ever there were one. Unfortunately the best you can do with class literals is Class<?>. I actually ran into this problem early on when moving to Wicket 1.4. I have a custom FormComponent that wraps another FormComponent and provides it with an associated Label. This object is meant for subclassing, to provide a text field with a label for instance. Prior to 1.4 the object took Class<? extends FormComponent> as an argument to its constructor and instantiated the wrapped component from that. Subclasses called super with their Class of choice. Enter 1.4 with FormComponent<T> and the Class argument becomes Class<? extends FormComponent<?>> (looks familiar, right?). It is impossible to provide such an object using class literals so I had to rethink the design. Frustrating? You bet! I understand why erasure was chosen but I feel it is too limiting sometimes. It seems that it is most visible in the instance of using Class objects. It makes for interesting discussions anyway...
________________________________ From: Sebastiaan van Erk [mailto:[EMAIL PROTECTED] Sent: Mon 6/9/2008 12:54 PM To: users@wicket.apache.org Subject: Re: (Class<? extends Page<?>>) casting troubles Zappaterrini, Larry wrote: > Sebastiaan, > > Point 1 is a good one. I haven't puzzled that through completely. Upon > initial inspection it seems that it is just the compiler being pedantic > about a scenario that wouldn't arise in practice. I'll have to think > about it some more. > > I might be missing something with point 2, but what is wrong with > Class<Foo> clazz = Foo.class? If Foo is a generic type (as in the example I gave), then the above assignment will give you a warning (which I don't know how to get rid off without a suppress)... Foo is a raw type. References to generic type Foo<T> should be parameterized Regards, Sebastiaan > Cheers, > Larry > > -----Original Message----- > From: Sebastiaan van Erk [mailto:[EMAIL PROTECTED] > Sent: Saturday, June 07, 2008 3:57 AM > To: users@wicket.apache.org > Subject: Re: (Class<? extends Page<?>>) casting troubles > > Zappaterrini, Larry wrote: >> Sorry, I should have been more clear about subtype. :) When dealing > with >> raw types, the raw type is considered a super type of the generic > type. >> So Bar is a super type of Bar<?>. Since RawType extends the raw type >> Bar, consider it to be a peer of Bar<?>. When you consider them as >> peers, a warning is warranted. The new example you use works due to >> erasure. Bar<?> as declared in source code becomes Bar in byte code. > So >> the statement becomes: >> >> Bar bar = new RawBar(); >> >> Which is perfectly legal. I have found that most of perceived >> inconsistencies in Java generics stems from erasure and sub type >> substitution. The golden rule of generics is that the byte code > produced >> by compiling generics will never produce an invalid cast so long as > the >> code does not produce any warnings. This causes some things that may >> seem intuitive to be illegal. > > Thanks for your explanation. I still think it's all rather horrible > though. Type erasure was a huge mistake if you ask me. Two questions for > > you though... > > 1) Can you come up with an example where assigning a Foo<? extends Bar> > to a Foo<? extends Bar<?>> causes an invalid cast? (So I can understand > why this intuitive seeming assignment is illegal). > > 2) How do you get rid of the warning in Class<Foo> clazz = Foo.class > without using Class<?>? Because it would seem strange if there is no > warning free way to use a certain language construct... > > Regards, > Sebastiaan > >> -----Original Message----- >> From: Sebastiaan van Erk [mailto:[EMAIL PROTECTED] >> Sent: Friday, June 06, 2008 4:16 PM >> To: users@wicket.apache.org >> Subject: Re: (Class<? extends Page<?>>) casting troubles >> >> Zappaterrini, Larry wrote: >>> In the example you have detailed, RawBar is not a subtype of Bar<?> >>> since it extends the raw type Bar. >> I guess it depends on the definition of subtype. It is at least the > case >> that the following assignment compiles without warnings (without >> warnings about unchecked casts): >> >> Bar<?> bar = new RawBar(); >> >> So is it then a subtype? Or isn't it? It's all terribly inconsistent > if >> you ask me. :-( >> >> Regards, >> Sebastiaan >> >> >> >>> -----Original Message----- >>> From: Sebastiaan van Erk [mailto:[EMAIL PROTECTED] >>> Sent: Friday, June 06, 2008 11:31 AM >>> To: users@wicket.apache.org >>> Subject: Re: (Class<? extends Page<?>>) casting troubles >>> >>> ARgh, you always make typos with this stuff. >>> >>> See correction. >>> >>> Sebastiaan van Erk wrote: >>>> Martin Funk wrote: >>>> >>>>>> Class<? extends Page<?>> means "class of (anything that extends >>> (page of >>>>>> anything))". >>>>> I'm not so sure. >>>> There are 2 separate issues: >>>> >>>> ISSUE 1: Foo<? extends Bar<?>> is not assignable from a Foo<RawBar> >>>> where RawBar extends Bar as a raw type. That is, given: >>>> >>>> static class Foo<T> { >>>> } >>>> >>>> static class Bar<T> { >>>> } >>>> >>>> static class RawBar extends Bar { >>>> } >>>> >>>> static class SubBar<T> extends Bar<T> { >>>> } >>>> >>>> Thus: >>>> >>>> Bar<?> bar = new RawBar(); // works, because RawBar is a subtype >> of >>>> Bar<?> >>>> >>>> But: >>>> >>>> Foo<? extends Bar<?>> rawbar = new RawBar(); // DOES NOT WORK - >>> THIS >>>> IS CAUSING ONE HALF OF ALL OUR HEADACHES >>> (correction:) >>> Foo<? extends Bar<?>> rawbar = new Foo<RawBar>(); // DOES NOT > WORK >> - >>> THIS IS CAUSING ONE HALF OF ALL OUR HEADACHES >>> >>> Btw, this does work (like you expect): >>> Foo<? extends Bar<?>> rawbar2 = new Foo<SubBar<?>>(); >>> >>>> Note that this is the issue that complete baffles me, as RawBar is a > >>>> subtype of Bar<?>, so I *really* *really* *REALLY* have no idea why >>> the >>>> compiler chokes on this. >>>> >>>> ISSUE 2: The class literal of a generic type returns a class of a > raw >>>> type. Thus Foo.class return Class<Foo>. This is also really messed >>> up, >>>> because: >>>> >>>> Class<Foo> fc = Foo.class; >>>> >>>> compiles, but generates a warning (reference to raw type). But if > you >>>> type this in eclipse: >>>> >>>> x fc = Foo.class; >>>> >>>> and use eclipse quickfix to change "x" to the "correct" type, it'll >>>> change it to precisely Class<Foo> (the JLS is very short about this, >>> see >>>> also >>>> > http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#1 >>> 5.8.2). >>>> So what the heck is the proper type for the class literal??? I >>> couldn't >>>> find any! >>>> >>>> Finally, note that when you define a method like this: >>>> >>>> static void method1(Foo<? extends Bar<?>> y) { >>>> } >>>> >>>> it works like a charm for a new Foo<SubBar<String>>, i.e., the "Foo >> of >>>> (anything that extends (bar of anything))" really is the correct >>>> interpretation. >>>> >>>> It's just that the interaction with raw types is completely *foobar* > >>>> (pun intended). >>>> >>>> Regards, >>>> Sebastiaan >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>> ______________ >>> >>> The information contained in this message is proprietary and/or >> confidential. If you are not the >>> intended recipient, please: (i) delete the message and all copies; >> (ii) do not disclose, >>> distribute or use the message in any manner; and (iii) notify the >> sender immediately. In addition, >>> please be aware that any message addressed to our domain is subject > to >> archiving and review by >>> persons other than the intended recipient. Thank you. >>> _____________ >>> >>> --------------------------------------------------------------------- >>> To unsubscribe, e-mail: [EMAIL PROTECTED] >>> For additional commands, e-mail: [EMAIL PROTECTED] >>> >> ______________ >> >> The information contained in this message is proprietary and/or > confidential. If you are not the >> intended recipient, please: (i) delete the message and all copies; > (ii) do not disclose, >> distribute or use the message in any manner; and (iii) notify the > sender immediately. In addition, >> please be aware that any message addressed to our domain is subject to > archiving and review by >> persons other than the intended recipient. Thank you. >> _____________ >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: [EMAIL PROTECTED] >> For additional commands, e-mail: [EMAIL PROTECTED] >> > > ______________ > > The information contained in this message is proprietary and/or confidential. > If you are not the > intended recipient, please: (i) delete the message and all copies; (ii) do > not disclose, > distribute or use the message in any manner; and (iii) notify the sender > immediately. In addition, > please be aware that any message addressed to our domain is subject to > archiving and review by > persons other than the intended recipient. Thank you. > _____________ > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > ______________ The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you. _____________
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]