Viktor Klang wrote: > Actually guys, referential equality is kind of retarded, so the > > Map<String,Integer>.class == Map<Foo,Bar>.class > > example is bad. > > However, > > Map<String,Integer>.class.equals(Map<Foo,Bar>.class) SHOULD return false No, it MUST not -- else loads of things break.
Further == and .equals MUST give the same results for Class objects -- else loads of things break. The "ConcreteClass" noted below would not be a Class -- it would be a new API. -- Jess Holle > On Thu, Nov 6, 2008 at 12:38 AM, Jess Holle <[EMAIL PROTECTED] > <mailto:[EMAIL PROTECTED]>> wrote: > > Peter Becker wrote: >> I think you probably want something like: >> >> Object -> ConcreteClass(String,Foo) -> GenericClass >> >> which adds the extra class instances, but they should be very small >> and not too many. >> >> Alternatively you could do: >> >> Object(String,Foo) -> GenericClass >> >> but then you'd have to store the type parameters on each object, which >> is probably much more expensive in total. The former approach seems to >> also match the type model better. >> > Yes, I was thinking something along the lines of the former. > >> On Thu, Nov 6, 2008 at 8:22 AM, Jess Holle <[EMAIL PROTECTED]> >> <mailto:[EMAIL PROTECTED]> wrote: >> >>> Peter Becker wrote: >>> >>> Sorry: I missed that parameter in your method. >>> >>> Wouldn't adding this information lead to a potential explosion of >>> Class instances at runtime similar to C++ templates? OTOH: there are >>> only a limited number of type parameters you'd actually use in your >>> code, so it is probably not too bad -- after all we wouldn't copy the >>> whole code as C++ does, just get a construct refering to the generic >>> class version and storing the type parameters. >>> >>> >>> Avoding this explosion is a benefit of erasure as well. Dealing with >>> C++ I >>> quickly had dozens and dozens of copies of the same (sizable) object >>> code >>> all due to instantiation with different types -- even where the usage >>> of the >>> types in question (e.g. char*, void*, int*, Foo*, etc, in a vector<>) >>> ended >>> up being 100% equivalent from an object code perspective. I don't want >>> to >>> go near that sort of issue again. >>> >>> That said, I see no reason to have separate Class objects for >>> Map<String,Foo> and Map<Bar,Baz>. This would lead to bloat and >>> incompatibility. >>> >>> Rather one could have something like a "GenericTypesMap", ala: >>> >>> For class Map<K,V>, Map<String,Foo> would have a GenericTypesMap of >>> {K->String,V->Foo} >>> >>> GenericTypesMap's could be shared across all instances which use the >>> same >>> instantation types and be weakly referenced by them or some such. >>> >>> I'm clearly just throwing together a strawman here, but the idea is to >>> have >>> a separate chunk of runtime data that spells out the generic types used >>> by >>> an instance without (1) breaking of existing Class contracts, explicit >>> or >>> implicit, (2) resulting in duplication of Class objects or other bloat, >>> or >>> (3) breaking interoperability between new and old code. >>> >>> -- >>> Jess Holle >>> >>> On Thu, Nov 6, 2008 at 7:47 AM, Jess Holle <[EMAIL PROTECTED]> >>> <mailto:[EMAIL PROTECTED]> wrote: >>> >>> >>> getTypeParameters() will tell you that Map<K,V> is parameterized by K >>> and V >>> and if/how these are contrained by wildcards. >>> >>> It won't tell you that the Map passed to your method is a >>> Map<String,Foo>, >>> though. Map.class covers the generic notion of Map<K,V> -- it knows >>> nothing >>> about how a particular instance was parameterized and there's no such >>> thing >>> as a Map<String,Foo>.class in terms of this being any different than >>> Map<K,V>. >>> >>> Peter Becker wrote: >>> >>> Like this: >>> >>> >>> >>> http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Class.html#getTypeParameters() >>> >>> <http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Class.html#getTypeParameters%28%29> >>> >>> ? >>> >>> Peter >>> >>> On Wed, Nov 5, 2008 at 2:35 PM, Jess Holle <[EMAIL PROTECTED]> >>> <mailto:[EMAIL PROTECTED]> wrote: >>> >>> >>> For the most part, Java 5 class files contain metadata indicating much >>> of >>> what the source file indicated as far as generics are concerned. This >>> is >>> certainly the case for field/method/class declarations. I'm not sure >>> about >>> local variable declarations, though. >>> >>> That said, once one has something like: >>> >>> void <T extends Foo> sort( List<T> list ) { ... } >>> >>> one can only determine that 'list' is parameterized by 'T', any >>> extends/super constraints, etc. The body of sort() here has no other >>> notions about T -- either in the class file or at runtime. That is >>> erasure. List<A>.class == List<B>.class == List.class. This is >>> necessary >>> to keep the existing contracts and is a key benefit to erasure -- both >>> in >>> lack of class bloat and in preservation of existing contracts and >>> compatibility. One could potentially have a special >>> Class.getGenericTypeInfos(Object) utility that could seperately lookup >>> this >>> info, e.g. by having each object refer to both its class and its generic >>> typing info -- rather than to just the class. When called by old, >>> non-generic-savvy code the generic typing info would be null, of course. >>> One could have the compiler do nifty bits with such a >>> getGenericTypeInfos() >>> utility so that one could do things like "new T[]" in sort -- throwing a >>> runtime exception if the typing info is not present. This would be >>> undoing >>> erasure without blowing new/old code interoperability except where >>> actually >>> necessary. >>> >>> -- >>> Jess Holle >>> >>> Christian Catchpole wrote: >>> >>> Here is my analysis of the situation. I could be wrong. But here >>> goes.. >>> >>> When I got my copy of Java 5 my first question was, do generics really >>> take the cast out of the equation? I disassembled the code to find >>> the cast still exists. This implies that when you compile this.. >>> >>> HashMap<String,String> map = new HashMap<String,String>() >>> String string = map.get(""); >>> >>> The generated code actually equates to this.. >>> >>> HashMap map = new HashMap() >>> String string = (String)map.get(""); >>> >>> The class returned by map.getClass() does not know the map only >>> contains Strings. It's actually the reference to the map which >>> marshals the types. >>> >>> I did a quick test... >>> >>> HashMap<String,String> map1 = new HashMap<String,String>(); >>> HashMap<Date,Date> map2 = new HashMap<Date,Date>(); >>> >>> System.out.println(map1.getClass() == map2.getClass()); >>> >>> true >>> >>> They use the same class and can't therefore hold the type information >>> for both declarations. >>> >>> I can only assume this re-compiler the posse were talking about, scans >>> the code for the actual cast / type check to determine the types. >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >> > > > > > > > -- > Viktor Klang > Senior Systems Analyst > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "The Java Posse" group. To post to this group, send email to javaposse@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/javaposse?hl=en -~----------~----~----~----~------~----~------~--~---