[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