[The Java Posse] Re: Fwd: [The Java Posse] Re: episode 215: reflection and generics
Marcelo, If instead of GenericTestE you replace with e.g. MapE what I interpret you are saying is that you can't tell from the (runtime) Map object what type E it is meant to be used with. However, the client of such an object *will* know the type, like this: public MapString,String map1 = new HashMapString,String(); Wouldn't a client using GenericTestE not include GenericTestString at compile time? Am I still missing something here? On Nov 11, 4:42 pm, Marcelo Fukushima [EMAIL PROTECTED] wrote: actually my point was that you can only get the generic type information in the cases where it is there in compile time but, for instance, imagine that you had this: public class GenericTestE { private ListE list = new ArrayListE(); } even if you create an instance of GenericTest with String, the generic type of the list field would be ParameterizedType and theres absolutely no way to get the String parameter you passed in the constructor - thats because in java, generics are implemented with erasure instead of reified types, in which case you could fetch the type information On 11/11/08, Tasos Zervos [EMAIL PROTECTED] wrote: Can you please give an example with some bits of code? I'm not sure what scenario you are trying to solve (or implying you can't solve). What are you going to use a Map?,? instance field for? (Would this be a Generics way of initialise a field?) On Nov 10, 10:27 pm, Marcelo Fukushima [EMAIL PROTECTED] wrote: just a quick observation: it only works because the maps you're trying to extract the generic info from, contains such information in the containing class file (the GenericTest fields specifically) - try changing the field types to Map?, ? and you wont the get info anymore, even tough you created the maps with the type information -- Forwarded message -- From: Tasos Zervos [EMAIL PROTECTED] Date: Mon, Nov 10, 2008 at 10:48 AM Subject: [The Java Posse] Re: episode 215: reflection and generics To: The Java Posse javaposse@googlegroups.com If you aren't keen to follow the article try this: import java.lang.reflect.*; import java.util.*; public class GenericTest { public HashMapString,String map1 = new HashMapString,String(); public HashMapDate,Date map2 = new HashMapDate,Date(); public static String fieldSignature(Object obj, String fieldName) throws SecurityException, NoSuchFieldException { StringBuffer signature = new StringBuffer(fieldName); Field field = GenericTest.class.getField(fieldName); Type genericFieldType = field.getGenericType(); if(genericFieldType instanceof ParameterizedType) { signature.append( is of type ).append(obj.getClass().getName()).append(); ParameterizedType aType = (ParameterizedType) genericFieldType; Type[] fieldArgTypes = aType.getActualTypeArguments(); for(Type fieldArgType : fieldArgTypes) { Class fieldArgClass = (Class) fieldArgType; signature.append(fieldArgClass.getName()).append(,); } signature.append(); } return signature.toString(); } public static void main(String[] args) throws SecurityException, NoSuchFieldException { GenericTest test = new GenericTest(); System.out.println(map1.getClass() == map2.getClass() is + (test.map1.getClass() == test.map2.getClass()) ); System.out.println(map1.getClass() is + test.map1.getClass()); System.out.println(map2.getClass() is + test.map2.getClass()); System.out.println(GenericTest.fieldSignature(test.map1, map1)); System.out.println(GenericTest.fieldSignature(test.map2, map2)); } } My quick test shows: map1.getClass() == map2.getClass() is true map1.getClass() is class java.util.HashMap map2.getClass() is class java.util.HashMap map1 is of type java.util.HashMapjava.lang.String,java.lang.String, map2 is of type java.util.HashMapjava.util.Date,java.util.Date, :-D Tasos On Nov 10, 12:46 pm, Tasos Zervos [EMAIL PROTECTED] wrote: The equality test has to return true otherwise you would be breaking compatibility with older code. This doesn't mean that there aren't other ways to find the signature of map1 and map2. The Reflection API does provide access to the specific types of generic signatures. Have a look at this 2005 article:http://www-128.ibm.com/developerworks/java/library/j-cwt11085.html#h2 The article series uses ASM (DRY) also later on. On Nov 4, 11:05 pm, Christian Catchpole [EMAIL PROTECTED] wrote: Here is my analysis of the situation. I could be wrong
[The Java Posse] Re: Fwd: [The Java Posse] Re: episode 215: reflection and generics
actually my point was that you can only get the generic type information in the cases where it is there in compile time but, for instance, imagine that you had this: public class GenericTestE { private ListE list = new ArrayListE(); } even if you create an instance of GenericTest with String, the generic type of the list field would be ParameterizedType and theres absolutely no way to get the String parameter you passed in the constructor - thats because in java, generics are implemented with erasure instead of reified types, in which case you could fetch the type information On 11/11/08, Tasos Zervos [EMAIL PROTECTED] wrote: Can you please give an example with some bits of code? I'm not sure what scenario you are trying to solve (or implying you can't solve). What are you going to use a Map?,? instance field for? (Would this be a Generics way of initialise a field?) On Nov 10, 10:27 pm, Marcelo Fukushima [EMAIL PROTECTED] wrote: just a quick observation: it only works because the maps you're trying to extract the generic info from, contains such information in the containing class file (the GenericTest fields specifically) - try changing the field types to Map?, ? and you wont the get info anymore, even tough you created the maps with the type information -- Forwarded message -- From: Tasos Zervos [EMAIL PROTECTED] Date: Mon, Nov 10, 2008 at 10:48 AM Subject: [The Java Posse] Re: episode 215: reflection and generics To: The Java Posse javaposse@googlegroups.com If you aren't keen to follow the article try this: import java.lang.reflect.*; import java.util.*; public class GenericTest { public HashMapString,String map1 = new HashMapString,String(); public HashMapDate,Date map2 = new HashMapDate,Date(); public static String fieldSignature(Object obj, String fieldName) throws SecurityException, NoSuchFieldException { StringBuffer signature = new StringBuffer(fieldName); Field field = GenericTest.class.getField(fieldName); Type genericFieldType = field.getGenericType(); if(genericFieldType instanceof ParameterizedType) { signature.append( is of type ).append(obj.getClass().getName()).append(); ParameterizedType aType = (ParameterizedType) genericFieldType; Type[] fieldArgTypes = aType.getActualTypeArguments(); for(Type fieldArgType : fieldArgTypes) { Class fieldArgClass = (Class) fieldArgType; signature.append(fieldArgClass.getName()).append(,); } signature.append(); } return signature.toString(); } public static void main(String[] args) throws SecurityException, NoSuchFieldException { GenericTest test = new GenericTest(); System.out.println(map1.getClass() == map2.getClass() is + (test.map1.getClass() == test.map2.getClass()) ); System.out.println(map1.getClass() is + test.map1.getClass()); System.out.println(map2.getClass() is + test.map2.getClass()); System.out.println(GenericTest.fieldSignature(test.map1, map1)); System.out.println(GenericTest.fieldSignature(test.map2, map2)); } } My quick test shows: map1.getClass() == map2.getClass() is true map1.getClass() is class java.util.HashMap map2.getClass() is class java.util.HashMap map1 is of type java.util.HashMapjava.lang.String,java.lang.String, map2 is of type java.util.HashMapjava.util.Date,java.util.Date, :-D Tasos On Nov 10, 12:46 pm, Tasos Zervos [EMAIL PROTECTED] wrote: The equality test has to return true otherwise you would be breaking compatibility with older code. This doesn't mean that there aren't other ways to find the signature of map1 and map2. The Reflection API does provide access to the specific types of generic signatures. Have a look at this 2005 article:http://www-128.ibm.com/developerworks/java/library/j-cwt11085.html#h2 The article series uses ASM (DRY) also later on. On Nov 4, 11:05 pm, Christian Catchpole [EMAIL PROTECTED] 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.. HashMapString,String map = new HashMapString,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
[The Java Posse] Re: Fwd: [The Java Posse] Re: episode 215: reflection and generics
Can you please give an example with some bits of code? I'm not sure what scenario you are trying to solve (or implying you can't solve). What are you going to use a Map?,? instance field for? (Would this be a Generics way of initialise a field?) On Nov 10, 10:27 pm, Marcelo Fukushima [EMAIL PROTECTED] wrote: just a quick observation: it only works because the maps you're trying to extract the generic info from, contains such information in the containing class file (the GenericTest fields specifically) - try changing the field types to Map?, ? and you wont the get info anymore, even tough you created the maps with the type information -- Forwarded message -- From: Tasos Zervos [EMAIL PROTECTED] Date: Mon, Nov 10, 2008 at 10:48 AM Subject: [The Java Posse] Re: episode 215: reflection and generics To: The Java Posse javaposse@googlegroups.com If you aren't keen to follow the article try this: import java.lang.reflect.*; import java.util.*; public class GenericTest { public HashMapString,String map1 = new HashMapString,String(); public HashMapDate,Date map2 = new HashMapDate,Date(); public static String fieldSignature(Object obj, String fieldName) throws SecurityException, NoSuchFieldException { StringBuffer signature = new StringBuffer(fieldName); Field field = GenericTest.class.getField(fieldName); Type genericFieldType = field.getGenericType(); if(genericFieldType instanceof ParameterizedType) { signature.append( is of type ).append(obj.getClass().getName()).append(); ParameterizedType aType = (ParameterizedType) genericFieldType; Type[] fieldArgTypes = aType.getActualTypeArguments(); for(Type fieldArgType : fieldArgTypes) { Class fieldArgClass = (Class) fieldArgType; signature.append(fieldArgClass.getName()).append(,); } signature.append(); } return signature.toString(); } public static void main(String[] args) throws SecurityException, NoSuchFieldException { GenericTest test = new GenericTest(); System.out.println(map1.getClass() == map2.getClass() is + (test.map1.getClass() == test.map2.getClass()) ); System.out.println(map1.getClass() is + test.map1.getClass()); System.out.println(map2.getClass() is + test.map2.getClass()); System.out.println(GenericTest.fieldSignature(test.map1, map1)); System.out.println(GenericTest.fieldSignature(test.map2, map2)); } } My quick test shows: map1.getClass() == map2.getClass() is true map1.getClass() is class java.util.HashMap map2.getClass() is class java.util.HashMap map1 is of type java.util.HashMapjava.lang.String,java.lang.String, map2 is of type java.util.HashMapjava.util.Date,java.util.Date, :-D Tasos On Nov 10, 12:46 pm, Tasos Zervos [EMAIL PROTECTED] wrote: The equality test has to return true otherwise you would be breaking compatibility with older code. This doesn't mean that there aren't other ways to find the signature of map1 and map2. The Reflection API does provide access to the specific types of generic signatures. Have a look at this 2005 article:http://www-128.ibm.com/developerworks/java/library/j-cwt11085.html#h2 The article series uses ASM (DRY) also later on. On Nov 4, 11:05 pm, Christian Catchpole [EMAIL PROTECTED] 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.. HashMapString,String map = new HashMapString,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... HashMapString,String map1 = new HashMapString,String(); HashMapDate,Date map2 = new HashMapDate,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. -- []'s Marcelo Takeshi Fukushima --~--~-~--~~~---~--~~ 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
[The Java Posse] Re: episode 215: reflection and generics
Episode #166 - Guillaume Laforge on Groovy also included Guillaume describing how Groovy gets the Generics info from Java [class-loaded] classes! Posse, posse... ;-) On Nov 6, 6:53 pm, Casper Bang [EMAIL PROTECTED] wrote: It's actually all described in chapter 7.5 of Java Generics and Collections which the Posse have endorsed in the past. Basically you can introspect it (look for ParameterizedType) and it can help you in a few instances, but in my humble experiences those solutions often turns ugly and fragile (played with that a while ago:http://coffeecokeandcode.blogspot.com/2008/05/type-strategy-pattern.html). /Casper On Nov 6, 3:13 pm, Jess Holle [EMAIL PROTECTED] wrote: Viktor Klang wrote: On Thu, Nov 6, 2008 at 1:49 PM, Jess Holle [EMAIL PROTECTED] mailto:[EMAIL PROTECTED] wrote: Viktor Klang wrote: Actually guys, referential equality is kind of retarded, so the MapString,Integer.class == MapFoo,Bar.class example is bad. However, MapString,Integer.class.equals(MapFoo,Bar.class) SHOULD return false No, it MUST not -- else loads of things break. If you want to make an omelet, you've got to break some eggs... Yes, but breaking eggs just cause you feel like it is for toddlers, not chefs. 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. Yeah, I realize that, that's why I'm moving away from Java. I'm still missing what the real benefit to having these Class objects be unequal is. It sounds nice in some ivory tower sort of way, but really as long as you have access to the fact that the K parameter is String and the V parameter is Integer (and the compiler can use this as well to do things like new V[]), I don't really see any issue. -- Jess Holle --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[The Java Posse] Re: episode 215: reflection and generics
If you aren't keen to follow the article try this: import java.lang.reflect.*; import java.util.*; public class GenericTest { public HashMapString,String map1 = new HashMapString,String(); public HashMapDate,Date map2 = new HashMapDate,Date(); public static String fieldSignature(Object obj, String fieldName) throws SecurityException, NoSuchFieldException { StringBuffer signature = new StringBuffer(fieldName); Field field = GenericTest.class.getField(fieldName); Type genericFieldType = field.getGenericType(); if(genericFieldType instanceof ParameterizedType) { signature.append( is of type ).append(obj.getClass().getName()).append(); ParameterizedType aType = (ParameterizedType) genericFieldType; Type[] fieldArgTypes = aType.getActualTypeArguments(); for(Type fieldArgType : fieldArgTypes) { Class fieldArgClass = (Class) fieldArgType; signature.append(fieldArgClass.getName()).append(,); } signature.append(); } return signature.toString(); } public static void main(String[] args) throws SecurityException, NoSuchFieldException { GenericTest test = new GenericTest(); System.out.println(map1.getClass() == map2.getClass() is + (test.map1.getClass() == test.map2.getClass()) ); System.out.println(map1.getClass() is + test.map1.getClass()); System.out.println(map2.getClass() is + test.map2.getClass()); System.out.println(GenericTest.fieldSignature(test.map1, map1)); System.out.println(GenericTest.fieldSignature(test.map2, map2)); } } My quick test shows: map1.getClass() == map2.getClass() is true map1.getClass() is class java.util.HashMap map2.getClass() is class java.util.HashMap map1 is of type java.util.HashMapjava.lang.String,java.lang.String, map2 is of type java.util.HashMapjava.util.Date,java.util.Date, :-D Tasos On Nov 10, 12:46 pm, Tasos Zervos [EMAIL PROTECTED] wrote: The equality test has to return true otherwise you would be breaking compatibility with older code. This doesn't mean that there aren't other ways to find the signature of map1 and map2. The Reflection API does provide access to the specific types of generic signatures. Have a look at this 2005 article:http://www-128.ibm.com/developerworks/java/library/j-cwt11085.html#h2 The article series uses ASM (DRY) also later on. On Nov 4, 11:05 pm, Christian Catchpole [EMAIL PROTECTED] 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.. HashMapString,String map = new HashMapString,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... HashMapString,String map1 = new HashMapString,String(); HashMapDate,Date map2 = new HashMapDate,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. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[The Java Posse] Re: episode 215: reflection and generics
The equality test has to return true otherwise you would be breaking compatibility with older code. This doesn't mean that there aren't other ways to find the signature of map1 and map2. The Reflection API does provide access to the specific types of generic signatures. Have a look at this 2005 article: http://www-128.ibm.com/developerworks/java/library/j-cwt11085.html#h2 The article series uses ASM (DRY) also later on. On Nov 4, 11:05 pm, Christian Catchpole [EMAIL PROTECTED] 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.. HashMapString,String map = new HashMapString,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... HashMapString,String map1 = new HashMapString,String(); HashMapDate,Date map2 = new HashMapDate,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. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[The Java Posse] Re: episode 215: reflection and generics
Ugly as heck, sure, but it works fine (for example, most of the generics-extended methods return a 'Type' which is little more than a flag interface - ironically, in order to do generics introspection, a device designed to avoid casts and instanceof checks, you need to litter your code with casts and instanceof checks!) For example, in an xml parser I wrote before I learned that there's such a thing as jaxb, I look at the generics part of a collection class to figure out how to parse the tags in a block of xml. This is a much nicer solution that forcing you to disregard the DRY principle and add an annotation. I admit thats the only time I really -needed- the feature to make something look good and work well, but in that one instance, I had no problems. Other than a block of somewhat ugly code. On Nov 6, 10:53 am, Casper Bang [EMAIL PROTECTED] wrote: It's actually all described in chapter 7.5 of Java Generics and Collections which the Posse have endorsed in the past. Basically you can introspect it (look for ParameterizedType) and it can help you in a few instances, but in my humble experiences those solutions often turns ugly and fragile (played with that a while ago:http://coffeecokeandcode.blogspot.com/2008/05/type-strategy-pattern.html). /Casper On Nov 6, 3:13 pm, Jess Holle [EMAIL PROTECTED] wrote: Viktor Klang wrote: On Thu, Nov 6, 2008 at 1:49 PM, Jess Holle [EMAIL PROTECTED] mailto:[EMAIL PROTECTED] wrote: Viktor Klang wrote: Actually guys, referential equality is kind of retarded, so the MapString,Integer.class == MapFoo,Bar.class example is bad. However, MapString,Integer.class.equals(MapFoo,Bar.class) SHOULD return false No, it MUST not -- else loads of things break. If you want to make an omelet, you've got to break some eggs... Yes, but breaking eggs just cause you feel like it is for toddlers, not chefs. 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. Yeah, I realize that, that's why I'm moving away from Java. I'm still missing what the real benefit to having these Class objects be unequal is. It sounds nice in some ivory tower sort of way, but really as long as you have access to the fact that the K parameter is String and the V parameter is Integer (and the compiler can use this as well to do things like new V[]), I don't really see any issue. -- Jess Holle --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[The Java Posse] Re: episode 215: reflection and generics
Actually guys, referential equality is kind of retarded, so the MapString,Integer.class == MapFoo,Bar.class example is bad. However, MapString,Integer.class.equals(MapFoo,Bar.class) SHOULD return false On Thu, Nov 6, 2008 at 12:38 AM, Jess Holle [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] [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 MapString,Foo and MapBar,Baz. This would lead to bloat and incompatibility. Rather one could have something like a GenericTypesMap, ala: For class MapK,V, MapString,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] [EMAIL PROTECTED] wrote: getTypeParameters() will tell you that MapK,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 MapString,Foo, though. Map.class covers the generic notion of MapK,V -- it knows nothing about how a particular instance was parameterized and there's no such thing as a MapString,Foo.class in terms of this being any different than MapK,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] [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( ListT 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. ListA.class == ListB.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
[The Java Posse] Re: episode 215: reflection and generics
On Thu, Nov 6, 2008 at 1:49 PM, Jess Holle [EMAIL PROTECTED] wrote: Viktor Klang wrote: Actually guys, referential equality is kind of retarded, so the MapString,Integer.class == MapFoo,Bar.class example is bad. However, MapString,Integer.class.equals(MapFoo,Bar.class) SHOULD return false No, it MUST not -- else loads of things break. If you want to make an omelet, you've got to break some eggs... 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. Yeah, I realize that, that's why I'm moving away from Java. -- Jess Holle On Thu, Nov 6, 2008 at 12:38 AM, Jess Holle [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] [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 MapString,Foo and MapBar,Baz. This would lead to bloat and incompatibility. Rather one could have something like a GenericTypesMap, ala: For class MapK,V, MapString,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] [EMAIL PROTECTED] wrote: getTypeParameters() will tell you that MapK,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 MapString,Foo, though. Map.class covers the generic notion of MapK,V -- it knows nothing about how a particular instance was parameterized and there's no such thing as a MapString,Foo.class in terms of this being any different than MapK,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] [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( ListT 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. ListA.class == ListB.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
[The Java Posse] Re: episode 215: reflection and generics
Viktor Klang wrote: On Thu, Nov 6, 2008 at 1:49 PM, Jess Holle [EMAIL PROTECTED] mailto:[EMAIL PROTECTED] wrote: Viktor Klang wrote: Actually guys, referential equality is kind of retarded, so the MapString,Integer.class == MapFoo,Bar.class example is bad. However, MapString,Integer.class.equals(MapFoo,Bar.class) SHOULD return false No, it MUST not -- else loads of things break. If you want to make an omelet, you've got to break some eggs... Yes, but breaking eggs just cause you feel like it is for toddlers, not chefs. 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. Yeah, I realize that, that's why I'm moving away from Java. I'm still missing what the real benefit to having these Class objects be unequal is. It sounds nice in some ivory tower sort of way, but really as long as you have access to the fact that the K parameter is String and the V parameter is Integer (and the compiler can use this as well to do things like new V[]), I don't really see any issue. -- Jess Holle --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[The Java Posse] Re: episode 215: reflection and generics
Viktor Klang wrote: Actually guys, referential equality is kind of retarded, so the MapString,Integer.class == MapFoo,Bar.class example is bad. However, MapString,Integer.class.equals(MapFoo,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 MapString,Foo and MapBar,Baz. This would lead to bloat and incompatibility. Rather one could have something like a GenericTypesMap, ala: For class MapK,V, MapString,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 MapK,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 MapString,Foo, though. Map.class covers the generic notion of MapK,V -- it knows nothing about how a particular instance was parameterized and there's no such thing as a MapString,Foo.class in terms of this being any different than MapK,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( ListT 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. ListA.class == ListB.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
[The Java Posse] Re: episode 215: reflection and generics
It's actually all described in chapter 7.5 of Java Generics and Collections which the Posse have endorsed in the past. Basically you can introspect it (look for ParameterizedType) and it can help you in a few instances, but in my humble experiences those solutions often turns ugly and fragile (played with that a while ago: http://coffeecokeandcode.blogspot.com/2008/05/type-strategy-pattern.html). /Casper On Nov 6, 3:13 pm, Jess Holle [EMAIL PROTECTED] wrote: Viktor Klang wrote: On Thu, Nov 6, 2008 at 1:49 PM, Jess Holle [EMAIL PROTECTED] mailto:[EMAIL PROTECTED] wrote: Viktor Klang wrote: Actually guys, referential equality is kind of retarded, so the MapString,Integer.class == MapFoo,Bar.class example is bad. However, MapString,Integer.class.equals(MapFoo,Bar.class) SHOULD return false No, it MUST not -- else loads of things break. If you want to make an omelet, you've got to break some eggs... Yes, but breaking eggs just cause you feel like it is for toddlers, not chefs. 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. Yeah, I realize that, that's why I'm moving away from Java. I'm still missing what the real benefit to having these Class objects be unequal is. It sounds nice in some ivory tower sort of way, but really as long as you have access to the fact that the K parameter is String and the V parameter is Integer (and the compiler can use this as well to do things like new V[]), I don't really see any issue. -- Jess Holle --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[The Java Posse] Re: episode 215: reflection and generics
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. Peter On Thu, Nov 6, 2008 at 7:47 AM, Jess Holle [EMAIL PROTECTED] wrote: getTypeParameters() will tell you that MapK,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 MapString,Foo, though. Map.class covers the generic notion of MapK,V -- it knows nothing about how a particular instance was parameterized and there's no such thing as a MapString,Foo.class in terms of this being any different than MapK,V. Peter Becker wrote: Like this: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Class.html#getTypeParameters() ? Peter On Wed, Nov 5, 2008 at 2:35 PM, Jess Holle [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( ListT 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. ListA.class == ListB.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.. HashMapString,String map = new HashMapString,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... HashMapString,String map1 = new HashMapString,String(); HashMapDate,Date map2 = new HashMapDate,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. -- What happened to Schroedinger's cat? My invisible saddled white dragon ate it. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[The Java Posse] Re: episode 215: reflection and generics
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 MapString,Foo and MapBar,Baz. This would lead to bloat and incompatibility. Rather one could have something like a GenericTypesMap, ala: For class MapK,V, MapString,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] wrote: getTypeParameters() will tell you that MapK,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 MapString,Foo, though. Map.class covers the generic notion of MapK,V -- it knows nothing about how a particular instance was parameterized and there's no such thing as a MapString,Foo.class in terms of this being any different than MapK,V. Peter Becker wrote: Like this: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Class.html#getTypeParameters() ? Peter On Wed, Nov 5, 2008 at 2:35 PM, Jess Holle [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( ListT 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. ListA.class == ListB.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.. HashMapString,String map = new HashMapString,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... HashMapString,String map1 = new HashMapString,String(); HashMapDate,Date map2 = new HashMapDate,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.
[The Java Posse] Re: episode 215: reflection and generics
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. Peter On Thu, Nov 6, 2008 at 8:22 AM, Jess Holle [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 MapString,Foo and MapBar,Baz. This would lead to bloat and incompatibility. Rather one could have something like a GenericTypesMap, ala: For class MapK,V, MapString,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] wrote: getTypeParameters() will tell you that MapK,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 MapString,Foo, though. Map.class covers the generic notion of MapK,V -- it knows nothing about how a particular instance was parameterized and there's no such thing as a MapString,Foo.class in terms of this being any different than MapK,V. Peter Becker wrote: Like this: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Class.html#getTypeParameters() ? Peter On Wed, Nov 5, 2008 at 2:35 PM, Jess Holle [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( ListT 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. ListA.class == ListB.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.. HashMapString,String map = new HashMapString,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
[The Java Posse] Re: episode 215: reflection and generics
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] 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 MapString,Foo and MapBar,Baz. This would lead to bloat and incompatibility. Rather one could have something like a GenericTypesMap, ala: For class MapK,V, MapString,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] wrote: getTypeParameters() will tell you that MapK,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 MapString,Foo, though. Map.class covers the generic notion of MapK,V -- it knows nothing about how a particular instance was parameterized and there's no such thing as a MapString,Foo.class in terms of this being any different than MapK,V. Peter Becker wrote: Like this: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Class.html#getTypeParameters() ? Peter On Wed, Nov 5, 2008 at 2:35 PM, Jess Holle [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( ListT 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. ListA.class == ListB.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.. HashMapString,String map = new HashMapString,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()
[The Java Posse] Re: episode 215: reflection and generics
What's funny, is that Joe was saying: If it's in the class file it should be in the reflection API as an extension... Well that's exactly how it goes. All the erased by erasure information is in the class file. So, you can query generics and annotations on a class file. The problem if you get a List object as a parameter here you lost the generics information (even if the class sending it to you knows). So, for framework that want to use generics information, you need the class object that contain the generic member, and of course to identify the member (Annotation or Ugly strings). That's where erasure hits and gets painful for framework. Keep up with good suppositions :) On Mon, Nov 3, 2008 at 4:45 PM, Alexey Zinger [EMAIL PROTECTED] wrote: In the discussion of the new Java decompiler that recognizes generics, the guys seemed to be surprised that class files can retain that information and were wondering why it's not in the reflection API. Without running a real test to see what's actually available, the API are most certainly there: http://java.sun.com/javase/6/docs/api/java/lang/reflect/GenericDeclaration.html Alexey 2001 Honda CBR600F4i (CCS) 1992 Kawasaki EX500 http://azinger.blogspot.com http://bsheet.sourceforge.net http://wcollage.sourceforge.net -- http://www.jfrog.org/ http://freddy33.blogspot.com/ http://nothingisinfinite.blogspot.com/ --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[The Java Posse] Re: episode 215: reflection and generics
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.. HashMapString,String map = new HashMapString,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... HashMapString,String map1 = new HashMapString,String(); HashMapDate,Date map2 = new HashMapDate,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. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[The Java Posse] Re: episode 215: reflection and generics
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( ListT 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. ListA.class == ListB.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.. HashMapString,String map = new HashMapString,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... HashMapString,String map1 = new HashMapString,String(); HashMapDate,Date map2 = new HashMapDate,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. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---