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 HashMap<String,String> map1 = new HashMap<String,String>();
   public HashMap<Date,Date> map2 = new HashMap<Date,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.HashMap<java.lang.String,java.lang.String,>
map2 is of type java.util.HashMap<java.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..
>
> > 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.




-- 
[]'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://groups.google.com/group/javaposse?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to