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 ) );
}
@[EMAIL PROTECTED]
({"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/>


|