Re: Can this callback mechanism be generified?
 
Casper Bang wrote:
Hello my fellow Java drinkers. I have a generics issue. Would it be 
possible to devise an API, which would allow me to register a callback 
*somewhere* associated with a class. Say I wish to allow a custom 
formatter to be installed:
1  interface Callback
2  {
3      String format(Object object);
4  }
5
6  class Somewhere
7  {
8      Map<Class, Callback> callbacks = new HashMap<Class, Callback>();
9
10     public void installCallback(Class clazz, Callback callback)
11     {
12         callbacks.put(clazz, callback);
13     }
14
15     public void doCallback(Object obj)
16     {
17         Callback callback = callbacks.get( obj.getClass() );
18         if(callback != null)
19             System.out.println( callback.format( obj ) );
20     }
21 }
22
23     somewhereInstance.installCallback( Date.class, new Callback(){
24         public String format(Object obj)
25         {
26             Date date = (Date)obj;
27             return SimpleDateFormat.getInstance().format(date);
28         }
29     });
The code works, but it requires casting as it very much revolves around 
a top-level Object. Is there any way to generify this, particularly the 
callback itself, since the type actually is known (line 23).
Thanks in advance,
Casper
This code should also work:
  interface Callback<T> {
      String format(T object);
  }
  class Somewhere {
      Map<Class<?>, Callback<?>> callbacks
           = new HashMap<Class<?>, Callback<?>>();
      public void installCallback(Class clazz, Callback callback) {
          callbacks.put(clazz, callback);
      }
      public <T> void doCallback(T obj) {
          final Callback<? super T> callback = getCallback(obj);
          if(callback != null)
              System.out.println( callback.format( obj ) );
      }
      @SuppressWarnings({"unchecked"})
      private <T> Callback<? super T> getCallback(T obj) {
          return (Callback<? super T>) callbacks.get(obj.getClass());
      }
  }
class Main {
     public static void main(String[] args) {
         new Somewhere().installCallback( Date.class,
         new Callback<Date>(){
             public String format(Date date) {
                 return SimpleDateFormat.getInstance().format(date);
             }
         });
     }
}
Of course, getCallback(T obj) should probably walk up the whole 
inheritance tree, because somewhere.doCallback(new java.sql.Date()) 
would have unexpected results.
-- 
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>